我们使用Nginx作为websocket应用程序的负载均衡器。每个后端服务器都会保留会话信息,因此客户端的每个请求都必须在同一服务器上转发。所以我们使用ip_hash
指令来实现这个目标:
upstream app {
ip_hash;
server 1;
}
当我们想要添加另一个后端服务器时,会出现问题:
upstream app {
ip_hash;
server 1;
server 2;
}
新的连接转到服务器1和服务器2 - 但这不是我们在这种情况下所需要的,因为服务器1上的负载继续增加 - 我们仍然需要粘性会话,但也启用了least_conn
算法 - 所以我们的两个服务器接收的负载大致相等。
我们还考虑使用Nginx-sticky-module
,但文档说如果没有可用的粘性cookie,它将回退到循环默认的Nginx算法 - 所以它也无法解决问题。
所以问题是我们可以使用Nginx组合粘性和最少连接逻辑吗?你知道其他负载均衡器能解决这个问题吗?
答案 0 :(得分:6)
可能使用split_clients模块可以提供帮助
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;
}
这将分割您的流量并创建您可以使用的变量$upstreap_app
,如下所示:
server {
location /some/path/ {
proxy_pass http://$upstream_app;
}
这是least_conn
和负载均衡器的解决方法,可以处理粘性会话,"缺点"如果需要添加更多服务器,则需要创建新流,例如:
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
有关此模块的更多信息,请参阅此文章(Performing A/B testing)
答案 1 :(得分:5)
您可以使用HAProxy轻松实现此目标,我确实建议您through it thoroughly查看当前设置如何受益。
使用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或任何其他算法,而无需担心会话。