diff options
-rw-r--r-- | man/coredns-proxy.7 | 4 | ||||
-rw-r--r-- | plugin/pkg/healthcheck/policy.go | 17 | ||||
-rw-r--r-- | plugin/pkg/healthcheck/policy_test.go | 25 | ||||
-rw-r--r-- | plugin/proxy/README.md | 4 |
4 files changed, 44 insertions, 6 deletions
diff --git a/man/coredns-proxy.7 b/man/coredns-proxy.7 index 888f784d7..9f1a785ed 100644 --- a/man/coredns-proxy.7 +++ b/man/coredns-proxy.7 @@ -38,7 +38,7 @@ However, advanced features including load balancing can be utilized with an expa .nf proxy FROM TO\.\.\. { - policy random|least_conn|round_robin + policy random|least_conn|round_robin|first fail_timeout DURATION max_fails INTEGER health_check PATH:PORT [DURATION] @@ -58,7 +58,7 @@ proxy FROM TO\.\.\. { \fBTO\fR is the destination endpoint to proxy to\. At least one is required, but multiple may be specified\. \fBTO\fR may be an IP:Port pair, or may reference a file in resolv\.conf format . .IP "\(bu" 4 -\fBpolicy\fR is the load balancing policy to use; applies only with multiple backends\. May be one of random, least_conn, or round_robin\. Default is random\. +\fBpolicy\fR is the load balancing policy to use; applies only with multiple backends\. May be one of random, least_conn, round_robin or first\. Default is random\. . .IP "\(bu" 4 \fBfail_timeout\fR specifies how long to consider a backend as down after it has failed\. While it is down, requests will not be routed to that backend\. A backend is "down" if CoreDNS fails to communicate with it\. The default value is 2 seconds ("2s")\. diff --git a/plugin/pkg/healthcheck/policy.go b/plugin/pkg/healthcheck/policy.go index 6a828fc4d..070213900 100644 --- a/plugin/pkg/healthcheck/policy.go +++ b/plugin/pkg/healthcheck/policy.go @@ -27,6 +27,7 @@ func init() { RegisterPolicy("random", func() Policy { return &Random{} }) RegisterPolicy("least_conn", func() Policy { return &LeastConn{} }) RegisterPolicy("round_robin", func() Policy { return &RoundRobin{} }) + RegisterPolicy("first", func() Policy { return &First{} }) } // Random is a policy that selects up hosts from a pool at random. @@ -118,3 +119,19 @@ func (r *RoundRobin) Select(pool HostPool) *UpstreamHost { } return host } + +// First is a policy that selects always the first healthy host in the list order. +type First struct{} + +// Select always the first that is not Down. +func (r *First) Select(pool HostPool) *UpstreamHost { + for i := 0; i < len(pool); i++ { + host := pool[i] + if host.Down() { + continue + } + return host + } + // return the first one, anyway none is correct + return nil +} diff --git a/plugin/pkg/healthcheck/policy_test.go b/plugin/pkg/healthcheck/policy_test.go index d3f03b7e3..ddf5a1415 100644 --- a/plugin/pkg/healthcheck/policy_test.go +++ b/plugin/pkg/healthcheck/policy_test.go @@ -32,8 +32,8 @@ func (r *customPolicy) Select(pool HostPool) *UpstreamHost { func testPool() HostPool { pool := []*UpstreamHost{ - {Name: workableServer.URL}, // this should resolve (healthcheck test) - {Name: "http://shouldnot.resolve"}, // this shouldn't + {Name: workableServer.URL}, // this should resolve (healthcheck test) + {Name: "http://shouldnot.resolve:85"}, // this shouldn't, especially on port other than 80 {Name: "http://C"}, } return HostPool(pool) @@ -136,3 +136,24 @@ func TestCustomPolicy(t *testing.T) { t.Error("Expected custom policy host to be the first host.") } } + +func TestFirstPolicy(t *testing.T) { + pool := testPool() + rrPolicy := &First{} + h := rrPolicy.Select(pool) + // First selected host is 1, because counter starts at 0 + // and increments before host is selected + if h != pool[0] { + t.Error("Expected always first to be first host in the pool.") + } + h = rrPolicy.Select(pool) + if h != pool[0] { + t.Error("Expected always first to be first host in the pool, even in second call") + } + // set this first in pool as failed + pool[0].Fails = 1 + h = rrPolicy.Select(pool) + if h != pool[1] { + t.Error("Expected first to be he second in pool if the first one is down.") + } +} diff --git a/plugin/proxy/README.md b/plugin/proxy/README.md index ce67c1d79..90357b135 100644 --- a/plugin/proxy/README.md +++ b/plugin/proxy/README.md @@ -25,7 +25,7 @@ However, advanced features including load balancing can be utilized with an expa ~~~ proxy FROM TO... { - policy random|least_conn|round_robin + policy random|least_conn|round_robin|first fail_timeout DURATION max_fails INTEGER health_check PATH:PORT [DURATION] @@ -39,7 +39,7 @@ proxy FROM TO... { * **TO** is the destination endpoint to proxy to. At least one is required, but multiple may be specified. **TO** may be an IP:Port pair, or may reference a file in resolv.conf format * `policy` is the load balancing policy to use; applies only with multiple backends. May be one of - random, least_conn, or round_robin. Default is random. + random, least_conn, round_robin or first. Default is random. * `fail_timeout` specifies how long to consider a backend as down after it has failed. While it is down, requests will not be routed to that backend. A backend is "down" if CoreDNS fails to communicate with it. The default value is 2 seconds ("2s"). |