Haproxy agent-检查DRAIN(agent)状态仍然接受新连接
Haproxy agent-check DRAIN(agent) status still accepts new connections
我正在尝试为使用 websockets 的 Node.js 应用程序执行负载平衡。我需要 haproxy 来停止负载平衡服务器上的新连接,该服务器已达到其最大连接数,同时保持现有连接的完整性。
我通过对我的每台服务器执行代理检查来做到这一点。如果服务器无法接受新连接,它会用 "drain" 响应代理检查。如果服务器能够响应新连接,它会用 "ready" 响应代理检查。
这是我的 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 returns HTTP 503。
更新:
原来我一直看错了方向
首先,我必须将处理 WebSocket 连接的后端标记为非 http(删除 mode http
行)。我的猜测是 haproxy 在使用 WebSockets 时错误地计算了 http 后端的当前会话。删除 mode http
解决了我的问题。
其次,在 agent-check 中返回 maxconn:<conn>
看起来是一种更简单、更惯用的限制并发连接数的方法。
来源:
- https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#5.2-agent-check
- https://www.haproxy.com/blog/websockets-load-balancing-with-haproxy/
我希望这会对某人有所帮助。
我正在尝试为使用 websockets 的 Node.js 应用程序执行负载平衡。我需要 haproxy 来停止负载平衡服务器上的新连接,该服务器已达到其最大连接数,同时保持现有连接的完整性。
我通过对我的每台服务器执行代理检查来做到这一点。如果服务器无法接受新连接,它会用 "drain" 响应代理检查。如果服务器能够响应新连接,它会用 "ready" 响应代理检查。
这是我的 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 returns HTTP 503。
更新: 原来我一直看错了方向
首先,我必须将处理 WebSocket 连接的后端标记为非 http(删除 mode http
行)。我的猜测是 haproxy 在使用 WebSockets 时错误地计算了 http 后端的当前会话。删除 mode http
解决了我的问题。
其次,在 agent-check 中返回 maxconn:<conn>
看起来是一种更简单、更惯用的限制并发连接数的方法。
来源:
- https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#5.2-agent-check
- https://www.haproxy.com/blog/websockets-load-balancing-with-haproxy/
我希望这会对某人有所帮助。