Do not make multiple requests to the same URL for balancer healthcheck
This commit is contained in:
parent
818541d4d7
commit
804b0ff2f2
2 changed files with 97 additions and 4 deletions
|
@ -375,17 +375,31 @@ func (lb *LbStatusUpdater) UpsertServer(u *url.URL, options ...roundrobin.Server
|
||||||
// Balancers is a list of Balancers(s) that implements the Balancer interface.
|
// Balancers is a list of Balancers(s) that implements the Balancer interface.
|
||||||
type Balancers []Balancer
|
type Balancers []Balancer
|
||||||
|
|
||||||
// Servers returns the servers url from all the BalancerHandler.
|
// Servers returns the deduplicated server URLs from all the Balancer.
|
||||||
|
// Note that the deduplication is only possible because all the underlying
|
||||||
|
// balancers are of the same kind (the oxy implementation).
|
||||||
|
// The comparison property is the same as the one found at:
|
||||||
|
// https://github.com/vulcand/oxy/blob/fb2728c857b7973a27f8de2f2190729c0f22cf49/roundrobin/rr.go#L347.
|
||||||
func (b Balancers) Servers() []*url.URL {
|
func (b Balancers) Servers() []*url.URL {
|
||||||
|
seen := make(map[string]struct{})
|
||||||
|
|
||||||
var servers []*url.URL
|
var servers []*url.URL
|
||||||
for _, lb := range b {
|
for _, lb := range b {
|
||||||
servers = append(servers, lb.Servers()...)
|
for _, server := range lb.Servers() {
|
||||||
|
key := serverKey(server)
|
||||||
|
if _, ok := seen[key]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
servers = append(servers, server)
|
||||||
|
seen[key] = struct{}{}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return servers
|
return servers
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveServer removes the given server from all the BalancerHandler,
|
// RemoveServer removes the given server from all the Balancer,
|
||||||
// and updates the status of the server to "DOWN".
|
// and updates the status of the server to "DOWN".
|
||||||
func (b Balancers) RemoveServer(u *url.URL) error {
|
func (b Balancers) RemoveServer(u *url.URL) error {
|
||||||
for _, lb := range b {
|
for _, lb := range b {
|
||||||
|
@ -396,7 +410,7 @@ func (b Balancers) RemoveServer(u *url.URL) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpsertServer adds the given server to all the BalancerHandler,
|
// UpsertServer adds the given server to all the Balancer,
|
||||||
// and updates the status of the server to "UP".
|
// and updates the status of the server to "UP".
|
||||||
func (b Balancers) UpsertServer(u *url.URL, options ...roundrobin.ServerOption) error {
|
func (b Balancers) UpsertServer(u *url.URL, options ...roundrobin.ServerOption) error {
|
||||||
for _, lb := range b {
|
for _, lb := range b {
|
||||||
|
@ -406,3 +420,7 @@ func (b Balancers) UpsertServer(u *url.URL, options ...roundrobin.ServerOption)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func serverKey(u *url.URL) string {
|
||||||
|
return u.Path + u.Host + u.Scheme
|
||||||
|
}
|
||||||
|
|
|
@ -362,6 +362,81 @@ func TestAddHeadersAndHost(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBalancers_Servers(t *testing.T) {
|
||||||
|
server1, err := url.Parse("http://foo.com")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
balancer1, err := roundrobin.New(nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
err = balancer1.UpsertServer(server1)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
server2, err := url.Parse("http://foo.com")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
balancer2, err := roundrobin.New(nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
err = balancer2.UpsertServer(server2)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
balancers := Balancers([]Balancer{balancer1, balancer2})
|
||||||
|
|
||||||
|
want, err := url.Parse("http://foo.com")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, 1, len(balancers.Servers()))
|
||||||
|
assert.Equal(t, want, balancers.Servers()[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBalancers_UpsertServer(t *testing.T) {
|
||||||
|
balancer1, err := roundrobin.New(nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
balancer2, err := roundrobin.New(nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
want, err := url.Parse("http://foo.com")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
balancers := Balancers([]Balancer{balancer1, balancer2})
|
||||||
|
|
||||||
|
err = balancers.UpsertServer(want)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, 1, len(balancer1.Servers()))
|
||||||
|
assert.Equal(t, want, balancer1.Servers()[0])
|
||||||
|
|
||||||
|
assert.Equal(t, 1, len(balancer2.Servers()))
|
||||||
|
assert.Equal(t, want, balancer2.Servers()[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBalancers_RemoveServer(t *testing.T) {
|
||||||
|
server, err := url.Parse("http://foo.com")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
balancer1, err := roundrobin.New(nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
err = balancer1.UpsertServer(server)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
balancer2, err := roundrobin.New(nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
err = balancer2.UpsertServer(server)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
balancers := Balancers([]Balancer{balancer1, balancer2})
|
||||||
|
|
||||||
|
err = balancers.RemoveServer(server)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, 0, len(balancer1.Servers()))
|
||||||
|
assert.Equal(t, 0, len(balancer2.Servers()))
|
||||||
|
}
|
||||||
|
|
||||||
type testLoadBalancer struct {
|
type testLoadBalancer struct {
|
||||||
// RWMutex needed due to parallel test execution: Both the system-under-test
|
// RWMutex needed due to parallel test execution: Both the system-under-test
|
||||||
// and the test assertions reference the counters.
|
// and the test assertions reference the counters.
|
||||||
|
|
Loading…
Reference in a new issue