A high-performance WebSocket connection balancer middleware for Traefik that distributes WebSocket connections across multiple backend pods based on their active connection count. This plugin is designed to ensure optimal load distribution for WebSocket-heavy applications.
Intelligent Load Balancing
WebSocket Support
Advanced Configuration
Pod-Level Monitoring
Monitoring & Debugging
git clone https://github.com/yourusername/traefikwsbalancer.gitcd traefikwsbalancer
go mod tidy
go build ./...
go run cmd/test-server/main.go
go run cmd/test-client/main.go
The balancer consists of three main components:
type Config struct {MetricPath string // Path to fetch connection metrics from backendsBalancerMetricPath string // Path to expose balancer's metricsServices []string // List of backend pod URLsTLSVerify bool // Enable/disable TLS verificationCacheTTL int // Metrics cache duration in seconds}
Each backend service must implement a /metric endpoint (or custom path configured in metricPath) that returns connection information. For pod-level metrics, the endpoint should include pod identification details.
app.get("/metric", (req, res) => {res.json({agentsConnections: activeConnections.size, // Number of active connectionspodName: process.env.POD_NAME, // Pod name from KubernetespodIP: process.env.POD_IP, // Pod IP from KubernetesnodeName: process.env.NODE_NAME // Node name from Kubernetes});});
app.get("/metric", (_req: Request, res: Response) => {res.json({agentsConnections: agentsConnections.size, // Number of active connectionspodName: process.env.POD_NAME, // Pod name from KubernetespodIP: process.env.POD_IP, // Pod IP from KubernetesnodeName: process.env.NODE_NAME // Node name from Kubernetes});});
http.HandleFunc("/metric", func(w http.ResponseWriter, r *http.Request) {metrics := struct {AgentsConnections int `json:"agentsConnections"`PodName string `json:"podName,omitempty"`PodIP string `json:"podIP,omitempty"`NodeName string `json:"nodeName,omitempty"`}{AgentsConnections: activeConnections.Count(),PodName: os.Getenv("POD_NAME"),PodIP: os.Getenv("POD_IP"),NodeName: os.Getenv("NODE_NAME"),}w.Header().Set("Content-Type", "application/json")json.NewEncoder(w).Encode(metrics)})
Your backend service should track active WebSocket connections. Here's a simple implementation in Node.js:
// Track active connectionsconst activeConnections = new Set();// WebSocket server setupconst wss = new WebSocketServer({ server });wss.on('connection', (ws) => {// Add connection to trackingactiveConnections.add(ws);ws.on('close', () => {// Remove connection from trackingactiveConnections.delete(ws);});});
The plugin provides a dedicated metrics endpoint that displays:
{"timestamp": "2025-04-06T20:02:59Z","services": [{"url": "http://service-1.namespace.svc.cluster.local:80","connections": 42}],"podMetrics": {"http://service-1.namespace.svc.cluster.local:80": [{"agentsConnections": 42,"podName": "service-1-pod-abc123","podIP": "10.0.0.1","nodeName": "node-1"}]},"totalConnections": 42,"agentsConnections": 42}
Security
Performance
Monitoring
# Static configuration in the Traefik config fileexperimental:plugins:traefikwsbalancer:moduleName: "github.com/K8Trust/traefikwsbalancer"version: "v1.0.26"# Dynamic configuration (Kubernetes CRD)apiVersion: traefik.io/v1alpha1kind: Middlewaremetadata:name: socket-balancernamespace: defaultspec:plugin:traefikwsbalancer:metricPath: "/metric"balancerMetricPath: "/balancer-metrics"services:- "http://service-1.namespace.svc.cluster.local:80"cacheTTL: 30
For pod-level metrics to work, ensure your pods expose their identities via environment variables in your deployment:
apiVersion: apps/v1kind: Deploymentmetadata:name: websocket-servicespec:template:spec:containers:- name: websocket-serviceenv:- name: POD_NAMEvalueFrom:fieldRef:fieldPath: metadata.name- name: POD_IPvalueFrom:fieldRef:fieldPath: status.podIP- name: NODE_NAMEvalueFrom:fieldRef:fieldPath: spec.nodeName
Connection Failures
Performance Issues
Protocol Errors
Missing Pod Metrics
Endpoint Implementation Issues
/metric endpoint returns valid JSONagentsConnections fieldEnable detailed logging:
log.SetFlags(log.Lshortfile | log.Ltime | log.Lmicroseconds)

MIT License
For issues and feature requests, please create an issue in the GitHub repository.