Nginx上游从serverA故障转移到serverB,然后回到serverA,为什么?

背景

我有以下Nginxconfiguration,这是负载平衡2台不同服务器上运行的Tomcat服务器:

### http://nginx.org/en/docs/http/ngx_http_upstream_module.html#hash upstream backend_w_affinity { hash $request_uri consistent; server 192.168.110.11:8080; server 192.168.110.12:8080; } server { listen 80 default_server; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; location ~ ^/path/to/rest/endpoint$ { proxy_pass http://backend_w_affinity; } } 

当我使用下面的curl命令来驱动Nginx的stream量时,它似乎很好。

 $ watch "curl -iI http://10.128.13.153/path/to/rest/endpoint" HTTP/1.1 401 Unauthorized Server: nginx/1.8.0 Date: Tue, 09 Jun 2015 01:31:13 GMT Content-Type: application/xml;charset=ISO-8859-1 Content-Length: 231 Connection: keep-alive 

注意:我意识到我得到401以上。 肯定有Tomcat的,如果我改变path,以便它指向Tomcat中的静态页面,以便我得到200的它仍然行为相同的方式,所以目前似乎不是一个问题。

起初似乎很好

运行上面的curl命令,我所有的stream量都被定向到第一个Tomcat服务器。 如果我停止了Tomcat,那么所有的stream量都会故障转移到第二个Tomcat服务器。

我的问题

当我把第一台Tomcat服务器备份时,我预计现在所有的stream量都保留在第二台服务器上。 但是一旦我将其重新启动,stream量就会被引导回第一个Tomcat服务器。

我该如何获得Nginx,将stream量保留在第二台服务器上,而不是将其redirect?

如果您想让stream量坚持到服务器,即使面对上游组成员的更改,您也需要使用“粘性”会话。 只要可用,一致的散列select相同的服务器,这不是你想要的。

在你的情况,你正在哈希的URI,如果你在nginx中使用proxy_cache,这是“caching局部性”的好处。 然而,一致的散列意味着一个服务器将永远是给定URI的“首选”,所以一旦它重新联机,nginx就会切换回它。

有来自第三方的开放源代码nginx可用的粘性会话模块 ,或在商业“NGINX Plus”中有本地粘性会话选项 。

没有附加模块或商业nginx订阅可以做粘性会话,但它有点难看。 您可以将map,proxy_pass与目标中的variables主机名以及回退位置组合使用。 您还需要在每个后端服务器中设置一个唯一的标识来标识它们(所以它们发送了一个“X-Loadbalace-ID”头,这可能是会话cookie的一部分,比如Tomcat JVM Route。因为它早于nginx上粘性会话的可用性。

像这样的东西可能会为你工作(未经testing的简化我们所做的):

 upstream backend_w_affinity { #use round-robin server 192.168.110.11:8080; server 192.168.110.12:8080; } server { listen 80 default_server; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; map $http_cookie_lb $mybackend { server1 192.168.110.11:8080; server2 192.168.110.12:8080; #default is something that will fail quickly #when no correct load balancing cookie is set #putting us into the named location that uses #the upstream block default 127.0.0.1:65432; } location ~ ^/path/to/rest/endpoint$ { proxy_pass http://$mybackend; #if the backend selected is down, fallback to upstream logic error_page 503 = @backend_down; } location @backend_down { proxy_pass http://backend_w_affinity; add_header "Set-Cookie" "lb=$upstream_http_X_Loadbalance_ID"; } }