2019-03-14 08:30:04 +00:00
|
|
|
package tcp
|
|
|
|
|
|
|
|
import (
|
|
|
|
"net"
|
|
|
|
"sync"
|
|
|
|
|
2019-03-15 08:42:03 +00:00
|
|
|
"github.com/containous/traefik/pkg/log"
|
2019-03-14 08:30:04 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// RRLoadBalancer is a naive RoundRobin load balancer for TCP services
|
|
|
|
type RRLoadBalancer struct {
|
|
|
|
servers []Handler
|
|
|
|
lock sync.RWMutex
|
|
|
|
current int
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewRRLoadBalancer creates a new RRLoadBalancer
|
|
|
|
func NewRRLoadBalancer() *RRLoadBalancer {
|
|
|
|
return &RRLoadBalancer{}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ServeTCP forwards the connection to the right service
|
|
|
|
func (r *RRLoadBalancer) ServeTCP(conn net.Conn) {
|
2019-05-09 12:30:06 +00:00
|
|
|
if len(r.servers) == 0 {
|
|
|
|
log.WithoutContext().Error("no available server")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2019-03-14 08:30:04 +00:00
|
|
|
r.next().ServeTCP(conn)
|
|
|
|
}
|
|
|
|
|
|
|
|
// AddServer appends a server to the existing list
|
|
|
|
func (r *RRLoadBalancer) AddServer(server Handler) {
|
|
|
|
r.servers = append(r.servers, server)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *RRLoadBalancer) next() Handler {
|
|
|
|
r.lock.Lock()
|
|
|
|
defer r.lock.Unlock()
|
|
|
|
|
|
|
|
// FIXME handle weight
|
|
|
|
if r.current >= len(r.servers) {
|
|
|
|
r.current = 0
|
|
|
|
log.Debugf("Load balancer: going back to the first available server")
|
|
|
|
}
|
2019-05-09 12:30:06 +00:00
|
|
|
|
2019-03-14 08:30:04 +00:00
|
|
|
handler := r.servers[r.current]
|
|
|
|
r.current++
|
|
|
|
return handler
|
|
|
|
}
|