我正在尝试对使用websocket的Node.js应用程序执行负载平衡。我需要haproxy来停止负载平衡服务器上的新连接,该连接已达到其最大连接数,同时保持了现有连接的完整性。
我通过对每个服务器执行代理检查来做到这一点。如果服务器不能接受新的连接,它将以“消耗”响应代理检查。如果服务器能够响应新的连接,则它将以“就绪”响应代理检查。
这是我的haproxy.cfg配置文件:
global
daemon
maxconn 240000
log /dev/log local0 debug
log /dev/log local1 notice
tune.ssl.default-dh-param 2048
defaults
mode http
log global
option httplog
option dontlognull
option dontlog-normal
option http-server-close
option redispatch
timeout connect 20000ms
timeout http-request 1m
timeout client 2100000ms
timeout server 2100000ms
timeout queue 30s
timeout check 5s
timeout http-keep-alive 180s
timeout tunnel 3600s
timeout tarpit 60s
frontend stats
bind *:8084
stats enable
stats uri /stats
stats refresh 10s
stats admin if TRUE
frontend test
mode http
bind *:5000
default_backend ws
backend ws
mode http
fullconn 100000
balance roundrobin
cookie SERVERID insert indirect nocache
server 1 backend1:9999 check agent-check agent-port 8080 cookie 1 inter 500 fall 1 rise 2
这是我在Node.js应用中对haproxy代理进行检查的方式:
const healthCheckServer = net.createServer((c) => {
let data = '';
if (currentConn < MAX_CONN) {
data += 'ready';
} else {
data += 'drain';
}
c.write(data + '\r\n');
c.destroy();
});
healthCheckServer.listen(8080, '0.0.0.0');
当与我的应用程序的连接数达到最大时,haproxy会将服务器状态正确更改为DRAIN (agent)
(我可以在haproxy Web仪表板中观察到此情况)。问题在于,新连接仍被应用程序接受。
我是haproxy的新手,所以有人可以指出我错了吗?
[发现代理服务器耗尽服务器的状态(状态设置为DRAIN (agent)
),并且如果服务器是后端中唯一的服务器,它将仍然接受新连接。
[当存在多个服务器并且每个服务器都被耗尽时,行为就像预期的一样:haproxy返回HTTP 503。
UPDATE:原来我一直在寻找错误的方向。
[首先,我必须将处理WebSocket连接的后端标记为非HTTP(删除mode http
行)。我的猜测是haproxy在使用WebSocket时错误地为http后端计数当前会话。删除mode http
解决了我的问题。
第二,在代理程序检查中返回maxconn:<conn>
似乎是限制并发连接数的非常简单和惯用的方式。
来源:
我希望这会对某人有所帮助。