【问题标题】:HAProxy closes long living TCP connections ignoring TCP keepaliveHAProxy 关闭长期存在的 TCP 连接,忽略 TCP keepalive
【发布时间】:2015-12-14 14:20:06
【问题描述】:

我已经配置了 HAProxy(1.5.4,但我也尝试了 1.5.14)以在 TCP 模式下平衡两个在 5672 端口上公开 AMQP 协议(​​WSO2 消息代理)的服务器。 客户端通过 HAProxy 创建并使用与 AMQP 服务器的永久连接。

我已更改客户端和服务器 TCP keepalive 超时,设置 net.ipv4.tcp_keepalive_time=120 (CentOS 7)。

在 HAProxy 中,我将客户端/服务器超时设置为 200 秒(>120 秒的 keepalive 数据包)并使用了选项 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 centos timeout amqp haproxy


    【解决方案1】:

    TCP keep alive 位于传输层,仅用于在连接上进行一些流量,因此像包过滤器这样的中间系统不会丢失任何状态,并且终端系统可以注意到如果与另一端的连接中断(可能是因为某些东西崩溃或网络电缆损坏)。

    TCP keep alive 与您明确设置为 200 秒的应用程序级空闲超时无关:

    timeout client 200000ms
    timeout server 200000ms
    

    如果连接空闲,即没有数据传输,则会触发此超时。 TCP keep alive 不传输任何数据,这些数据包的payload是空的。

    【讨论】:

    • 我不是 HAProxy 专家,但似乎它在 TCP 级别运行,如 serverfault.com/questions/589804/… 中所述
    • @PaoloParlato:TCP 级别很大 :) HA 代理工作在用户空间端,您可以控制保持活动计时器,但不能直接发送或接收 TCP 保持活动数据包。您只能读取和写入大小超过 0 字节的真实数据,并且保持活动数据包为空。同样,HA 代理中的空闲超时只关心数据传输,而 TCP 保持活动不传输任何数据。
    【解决方案2】:

    timeout client 在响应式客户端操作系统上检测到死客户端应用程序。您始终可以拥有一个占用连接但不与您通话的应用程序。这很糟糕,因为连接数不是无限的 (maxconn)。

    同样,为后端设置timeout server

    这些选项用于 haproxy 与应用程序的对话。现在,有一个完全独立的检查 OS 与 OS 的对话(不接触应用程序或 haproxy):

    使用option clitcpkaoption srvtcpkaoption tcpka 您允许操作系统检测并终止非活动连接,即使haproxy 没有主动检查它。这主要需要操作系统设置(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
    

    在这种情况下,操作系统会在数据包停止发送 200 秒后终止连接。

    【讨论】:

      猜你喜欢
      • 2011-07-12
      • 2014-06-28
      • 2020-11-30
      • 2013-09-04
      • 1970-01-01
      • 1970-01-01
      • 2012-04-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多