HAProxy 关闭长期存在的 TCP 连接,忽略 TCP keepalive
HAProxy closes long living TCP connections ignoring TCP keepalive
我已经配置了 HAProxy(1.5.4,但我也尝试过 1.5.14)以在 TCP 模式下平衡两个在 5672 端口上公开 AMQP 协议(WSO2 Message Broker)的服务器。
客户端通过 HAProxy 创建并使用与 AMQP 服务器的永久连接。
我已经更改了客户端和服务器 TCP keepalive 超时,设置为 net.ipv4.tcp_keepalive_time=120 (CentOS 7).
在 HAProxy 中,我将超时 client/server 设置为 200 秒(>120 秒的保活数据包)并使用选项 clitcpka。
然后我启动了 wireshark 并嗅探了所有 tcp 流量:在客户端发出最后一个请求后,tcp keepalived 数据包在 120 秒后定期发送,但在客户端发出最后一个请求后 200 秒后,连接关闭(因此忽略 keepalived 数据包)。
配置如下:
haproxy.conf
global
log 127.0.0.1 local3
maxconn 4096
user haproxy
group haproxy
daemon
debug
listen messagebroker_balancer 172.19.19.91:5672
mode tcp
log global
retries 3
timeout connect 5000ms
option redispatch
timeout client 200000ms
timeout server 200000ms
option tcplog
option clitcpka
balance leastconn
server s1 172.19.19.79:5672 check inter 5s rise 2 fall 3
server s2 172.19.19.80:5672 check inter 5s rise 2 fall 3
TCP keep alive 位于传输层,仅用于连接上的一些流量,因此 中间 系统(如数据包过滤器)不会丢失任何状态,并且结束系统可以注意到与另一端的连接是否断开(可能是因为崩溃或网络电缆断开)。
TCP keep alive 与您明确设置为 200 秒的应用程序级空闲超时无关:
timeout client 200000ms
timeout server 200000ms
如果连接空闲,即没有数据传输,则会触发此超时。 TCP keep alive 不传输任何数据,这些数据包的负载是空的。
timeout client
在响应客户端 OS 上检测到死客户端应用程序。您总是可以拥有一个占用连接但不与您通话的应用程序。这很糟糕,因为连接数不是无限的 (maxconn
)。
同理,后端设置timeout server
。
这些选项用于 haproxy 与应用程序对话。现在,有一个完全独立的检查,其中 OS 与 OS 对话(不接触应用程序或 haproxy):
使用 option clitcpka
或 option srvtcpka
或 option tcpka
您允许 OS 检测并终止非活动连接,即使 haproxy 不主动检查它.这主要需要 OS 设置 (Linux).
如果 110 秒内没有发送数据,则立即发送第一个 keep-alive (KA),但不要终止连接:
sysctl net.ipv4.tcp_keepalive_time=110
每次 KA 后等待 30 秒,在此连接上启用后:
sysctl net.ipv4.tcp_keepalive_intvl=30
允许 3 个 KA 未被确认,然后终止 TCP 连接:
sysctl net.ipv4.tcp_keepalive_probes=3
在这种情况下,OS 在数据包停止到来 200 秒后终止连接。
我已经配置了 HAProxy(1.5.4,但我也尝试过 1.5.14)以在 TCP 模式下平衡两个在 5672 端口上公开 AMQP 协议(WSO2 Message Broker)的服务器。 客户端通过 HAProxy 创建并使用与 AMQP 服务器的永久连接。
我已经更改了客户端和服务器 TCP keepalive 超时,设置为 net.ipv4.tcp_keepalive_time=120 (CentOS 7).
在 HAProxy 中,我将超时 client/server 设置为 200 秒(>120 秒的保活数据包)并使用选项 clitcpka。
然后我启动了 wireshark 并嗅探了所有 tcp 流量:在客户端发出最后一个请求后,tcp keepalived 数据包在 120 秒后定期发送,但在客户端发出最后一个请求后 200 秒后,连接关闭(因此忽略 keepalived 数据包)。
配置如下:
haproxy.conf
global
log 127.0.0.1 local3
maxconn 4096
user haproxy
group haproxy
daemon
debug
listen messagebroker_balancer 172.19.19.91:5672
mode tcp
log global
retries 3
timeout connect 5000ms
option redispatch
timeout client 200000ms
timeout server 200000ms
option tcplog
option clitcpka
balance leastconn
server s1 172.19.19.79:5672 check inter 5s rise 2 fall 3
server s2 172.19.19.80:5672 check inter 5s rise 2 fall 3
TCP keep alive 位于传输层,仅用于连接上的一些流量,因此 中间 系统(如数据包过滤器)不会丢失任何状态,并且结束系统可以注意到与另一端的连接是否断开(可能是因为崩溃或网络电缆断开)。
TCP keep alive 与您明确设置为 200 秒的应用程序级空闲超时无关:
timeout client 200000ms timeout server 200000ms
如果连接空闲,即没有数据传输,则会触发此超时。 TCP keep alive 不传输任何数据,这些数据包的负载是空的。
timeout client
在响应客户端 OS 上检测到死客户端应用程序。您总是可以拥有一个占用连接但不与您通话的应用程序。这很糟糕,因为连接数不是无限的 (maxconn
)。
同理,后端设置timeout server
。
这些选项用于 haproxy 与应用程序对话。现在,有一个完全独立的检查,其中 OS 与 OS 对话(不接触应用程序或 haproxy):
使用 option clitcpka
或 option srvtcpka
或 option tcpka
您允许 OS 检测并终止非活动连接,即使 haproxy 不主动检查它.这主要需要 OS 设置 (Linux).
如果 110 秒内没有发送数据,则立即发送第一个 keep-alive (KA),但不要终止连接:
sysctl net.ipv4.tcp_keepalive_time=110
每次 KA 后等待 30 秒,在此连接上启用后:
sysctl net.ipv4.tcp_keepalive_intvl=30
允许 3 个 KA 未被确认,然后终止 TCP 连接:
sysctl net.ipv4.tcp_keepalive_probes=3
在这种情况下,OS 在数据包停止到来 200 秒后终止连接。