Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
Mirrored from https://github.com/Slazee/caddy.git
Synced Nov 13, 09:15 UTC
reverseproxy: Improve hostByHashing distribution (#5229)
* If upstreams are all using same host but with different ports ie: foobar:4001 foobar:4002 foobar:4003 ... Because fnv-1a has not a good enough avalanche effect Then the hostByHashing result is not well balanced over all upstreams As last byte FNV input tend to affect few bits, the idea is to change the concatenation order between the key and the upstream strings So the upstream last byte have more impact on hash diffusion
Alban Lecocq committed
Dec 5, 2022 at 19:28 UTC
d4a7d89f564234e44012a763cc28c5a3991bd98e
2 files changed
+23
-23
modules/caddyhttp/reverseproxy/selectionpolicies.go
+1
-1
@@ -528,7 +528,7 @@ func hostByHashing(pool []*Upstream, s string) *Upstream {
528
if !up.Available() {
529
continue
530
}
531
- h := hash(s + up.String()) // important to hash key and server together
531
+ h := hash(up.String() + s) // important to hash key and server together
532
if h > highestHash {
533
highestHash = h
534
upstream = up
modules/caddyhttp/reverseproxy/selectionpolicies_test.go
+22
-22
@@ -95,18 +95,18 @@ func TestIPHashPolicy(t *testing.T) {
95
// We should be able to predict where every request is routed.
96
req.RemoteAddr = "172.0.0.1:80"
97
h := ipHash.Select(pool, req, nil)
98
- if h != pool[0] {
99
- t.Error("Expected ip hash policy host to be the first host.")
98
+ if h != pool[1] {
99
+ t.Error("Expected ip hash policy host to be the second host.")
100
}
101
req.RemoteAddr = "172.0.0.2:80"
102
h = ipHash.Select(pool, req, nil)
103
- if h != pool[0] {
104
- t.Error("Expected ip hash policy host to be the first host.")
103
+ if h != pool[1] {
104
+ t.Error("Expected ip hash policy host to be the second host.")
105
}
106
req.RemoteAddr = "172.0.0.3:80"
107
h = ipHash.Select(pool, req, nil)
108
- if h != pool[2] {
109
- t.Error("Expected ip hash policy host to be the third host.")
108
+ if h != pool[1] {
109
+ t.Error("Expected ip hash policy host to be the second host.")
110
}
111
req.RemoteAddr = "172.0.0.4:80"
112
h = ipHash.Select(pool, req, nil)
@@ -117,18 +117,18 @@ func TestIPHashPolicy(t *testing.T) {
117
// we should get the same results without a port
118
req.RemoteAddr = "172.0.0.1"
119
h = ipHash.Select(pool, req, nil)
120
- if h != pool[0] {
121
- t.Error("Expected ip hash policy host to be the first host.")
120
+ if h != pool[1] {
121
+ t.Error("Expected ip hash policy host to be the second host.")
122
}
123
req.RemoteAddr = "172.0.0.2"
124
h = ipHash.Select(pool, req, nil)
125
- if h != pool[0] {
126
- t.Error("Expected ip hash policy host to be the first host.")
125
+ if h != pool[1] {
126
+ t.Error("Expected ip hash policy host to be the second host.")
127
}
128
req.RemoteAddr = "172.0.0.3"
129
h = ipHash.Select(pool, req, nil)
130
- if h != pool[2] {
131
- t.Error("Expected ip hash policy host to be the third host.")
130
+ if h != pool[1] {
131
+ t.Error("Expected ip hash policy host to be the second host.")
132
}
133
req.RemoteAddr = "172.0.0.4"
134
h = ipHash.Select(pool, req, nil)
@@ -141,8 +141,8 @@ func TestIPHashPolicy(t *testing.T) {
141
req.RemoteAddr = "172.0.0.4"
142
pool[1].setHealthy(false)
143
h = ipHash.Select(pool, req, nil)
144
- if h != pool[2] {
145
- t.Error("Expected ip hash policy host to be the third host.")
144
+ if h != pool[0] {
145
+ t.Error("Expected ip hash policy host to be the first host.")
146
}
147
148
req.RemoteAddr = "172.0.0.2"
@@ -172,8 +172,8 @@ func TestIPHashPolicy(t *testing.T) {
172
}
173
req.RemoteAddr = "172.0.0.1:80"
174
h = ipHash.Select(pool, req, nil)
175
- if h != pool[1] {
176
- t.Error("Expected ip hash policy host to be the second host.")
175
+ if h != pool[0] {
176
+ t.Error("Expected ip hash policy host to be the first host.")
177
}
178
req.RemoteAddr = "172.0.0.2:80"
179
h = ipHash.Select(pool, req, nil)
@@ -182,8 +182,8 @@ func TestIPHashPolicy(t *testing.T) {
182
}
183
req.RemoteAddr = "172.0.0.3:80"
184
h = ipHash.Select(pool, req, nil)
185
- if h != pool[1] {
186
- t.Error("Expected ip hash policy host to be the second host.")
185
+ if h != pool[0] {
186
+ t.Error("Expected ip hash policy host to be the first host.")
187
}
188
req.RemoteAddr = "172.0.0.4:80"
189
h = ipHash.Select(pool, req, nil)
@@ -252,8 +252,8 @@ func TestURIHashPolicy(t *testing.T) {
252
253
request := httptest.NewRequest(http.MethodGet, "/test", nil)
254
h := uriPolicy.Select(pool, request, nil)
255
- if h != pool[2] {
256
- t.Error("Expected uri policy host to be the third host.")
255
+ if h != pool[1] {
256
+ t.Error("Expected uri policy host to be the second host.")
257
}
258
259
pool[2].setHealthy(false)
@@ -264,8 +264,8 @@ func TestURIHashPolicy(t *testing.T) {
264
265
request = httptest.NewRequest(http.MethodGet, "/test_2", nil)
266
h = uriPolicy.Select(pool, request, nil)
267
- if h != pool[1] {
268
- t.Error("Expected uri policy host to be the second host.")
267
+ if h != pool[0] {
268
+ t.Error("Expected uri policy host to be the first host.")
269
}
270
271
// We should be able to resize the host pool and still be able to predict