Nginx,同时使用粘性和最少连接算法的负载平衡

Nginx,同时使用粘性和最少连接算法的负载平衡,nginx,load-balancing,reverse-proxy,Nginx,Load Balancing,Reverse Proxy,我们使用Nginx作为websocket应用程序的负载平衡器。每个后端服务器都保存会话信息,因此来自客户端的每个请求都必须在同一服务器上转发。因此,我们使用ip_hash指令来实现这一点: upstream app { ip_hash; server 1; } 当我们要添加另一个后端服务器时出现问题: upstream app { ip_hash; server 1; server 2; } 新的连接连接到服务器1和服务器2-但这不是我们在这种情况下需

我们使用Nginx作为websocket应用程序的负载平衡器。每个后端服务器都保存会话信息,因此来自客户端的每个请求都必须在同一服务器上转发。因此,我们使用
ip_hash
指令来实现这一点:

upstream app {
    ip_hash;
    server 1;
}
当我们要添加另一个后端服务器时出现问题:

upstream app {
    ip_hash;
    server 1;
    server 2;
}
新的连接连接到服务器1和服务器2-但这不是我们在这种情况下需要的,因为服务器1上的负载继续增加-我们仍然需要粘性会话,但也启用了
最小连接算法-因此我们的两台服务器接收的负载大致相等

我们还考虑使用
Nginx sticky module
,但文档中说,如果没有可用的sticky cookie,它将退回到循环默认Nginx算法-因此它也不能解决问题

所以问题是,我们可以使用Nginx将粘性逻辑和最少连接逻辑结合起来吗?您知道其他哪些负载平衡器可以解决此问题吗?

使用此模块可能会有所帮助

upstream app {
    ip_hash;
    server 127.0.0.1:8001;
}

upstream app_new {
    ip_hash;
    server 127.0.0.1:8002;
}

split_clients "${remote_addr}AAA" $upstream_app {
    50% app_new;
    *   app;
}
这将分割您的流量并创建变量
$upstreamp\u app
您可以使用的变量,如:

server {
   location /some/path/ {
   proxy_pass http://$upstream_app;
}
这是
最小连接
和使用粘性会话的负载平衡器的一个解决方案,“缺点”是如果需要添加更多服务器,则需要创建一个新流,例如:

split_clients "${remote_addr}AAA" $upstream_app {
    30% app_another_server;
    30% app_new;
    *   app;
}
对于测试:

for x in {1..10}; do \
  curl "0:8080?token=$(LC_ALL=C; cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)"; done

关于这个模块的更多信息可以在本文中找到()

您可以很容易地通过使用来实现这一点,我确实建议您去看看您当前的设置是如何受益的

使用HA Proxy,您将获得以下内容:

backend nodes
    # Other options above omitted for brevity
    cookie SRV_ID prefix
    server web01 127.0.0.1:9000 cookie check
    server web02 127.0.0.1:9001 cookie check
    server web03 127.0.0.1:9002 cookie check
这仅仅意味着代理通过使用cookie来跟踪往返于服务器的请求


但是,如果您不想使用HAProxy,我建议您将会话实现更改为使用内存中的数据库,如redis/memcached。这样,您就可以使用leastconn或任何其他算法,而不必担心会话。

也许应该将此移到serverfault以获得答案?有趣的问题是,为什么“服务器1上的负载继续增加”-是否大多数用户都坐在相同或很少的NAT后面?在这种情况下,对源IP的散列是不有效的,并且可以考虑通过使用代码> >散列指令来使用更复杂的密钥,而不是“IPHASH”。例如,您可能希望在密钥中添加一些特定于用户的URI部分或参数…有用的答案,但我不确定他们是否回答了最初提出的问题。Alex?注意,
split_客户端将使用一致的哈希进行负载平衡,这可能比round robin好,也可能不比round robin好,但不是op要求的(至少基于连接的负载平衡)