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

Ale*_*lin 15 reverse-proxy load-balancing nginx

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

upstream app {
    ip_hash;
    server 1;
}
Run Code Online (Sandbox Code Playgroud)

当我们想要添加另一个后端服务器时,会出现问题:

upstream app {
    ip_hash;
    server 1;
    server 2;
}
Run Code Online (Sandbox Code Playgroud)

新的连接转到服务器1和服务器2 - 但这不是我们在这种情况下需要的,因为服务器1上的负载继续增加 - 我们仍然需要粘性会话但是也least_conn启用了算法 - 所以我们的两台服务器接收的负载大致相等.

我们也考虑过使用Nginx-sticky-module但文档说如果没有可用的粘性cookie,它将回退到循环默认的Nginx算法 - 所以它也没有解决问题.

所以问题是我们可以使用Nginx组合粘性和最少连接逻辑吗?你知道其他负载均衡器能解决这个问题吗?

nba*_*ari 7

可能使用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;
}
Run Code Online (Sandbox Code Playgroud)

这将分割您的流量并创建$upstreap_app您可以使用的变量,如:

server {
   location /some/path/ {
   proxy_pass http://$upstream_app;
}
Run Code Online (Sandbox Code Playgroud)

这是least_conn与粘性会话一起使用的负载均衡器的解决方法,"缺点"是如果需要添加更多服务器,则需要创建新流,例如:

split_clients "${remote_addr}AAA" $upstream_app {
    30% app_another_server;
    30% app_new;
    *   app;
}
Run Code Online (Sandbox Code Playgroud)

用于检测:

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
Run Code Online (Sandbox Code Playgroud)

有关此模块的更多信息可以在本文中找到(执行A/B测试)


Chi*_*ata 6

你可以使用HAProxy轻松实现这一点,我确实建议彻底了解,看看你当前的设置如何受益.

使用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
Run Code Online (Sandbox Code Playgroud)

这仅仅意味着代理通过使用cookie跟踪服务器的来回请求.

但是,如果您不想使用HAProxy,我建议您设置更改会话实现以使用内存数据库,例如redis/memcached.这样,您可以使用leastconn或任何其他算法,而无需担心会话.