需要帮助解决HAProxy中的间歇性TCP超时问题

我有一个应用程序,客户端通过基于TLS / SSL的简单TCP协议连接到服务器。 在开发过程中,在我们构build应用程序的过程中,这已经运行了好几个月。 最近,当我们准备启动时,我已经提前将HAProxy添加到混合中,以便实现一些负载分配的顺序。 从技术上讲,一切都是有效的,但问题是,客户现在看到了完全随机的超时。 它们通常不一致,但发生时间大约为60秒。 有时会在25秒后发生。 haproxy转发TCP连接的服务器来通知并做一个干净的断开连接,问题是你不希望大量的同时连接中断和重新连接,没有任何理由反复。 除了其他方面之外,这对我们的发布/订阅基础设施也有影响。 客户很聪明,可以马上重新连接 – 但是这不是我们想要的行为。 负责通过SSL接受这些TCP连接的服务器不需要保持活动状态。 我将继续,并假设有一些隐含的价值,我没有看到我的HAProxyconfiguration造成这些随机超时,或需要一个TCP保持活着的东西。 事实上,超时并不总是一致的,但是,让我怀疑,否则。 如果每一次我都相信这是一个configuration问题,那么这个点就是60秒。 在这种情况下,并不总是60秒。 以下是我现在的configuration:

global stats socket /home/haproxy/status user haproxy group haproxy log 127.0.0.1 local1 info # log 127.0.0.1 local5 info maxconn 4096 ulimit-n 8250 # typically: /home/haproxy chroot /home/haproxy user haproxy group haproxy daemon quiet pidfile /home/haproxy/haproxy.pid defaults log global mode http option httplog option dontlognull retries 3 option redispatch maxconn 2000 contimeout 5000 clitimeout 60000 srvtimeout 60000 # Configuration for one application: # Example: listen myapp 0.0.0.0:80 listen www 0.0.0.0:443 mode tcp balance leastconn # Example server line (with optional cookie and check included) # server srv3.0 10.253.43.224:8000 srv03.0 check inter 2000 rise 2 fall 3 # Status port (by default, localhost only...for debugging purposes) server ANID3 10.0.1.2:8888 check inter 3000 rise 2 fall 3 maxconn 500 server ANID1 10.0.1.3:8888 check inter 3000 rise 2 fall 3 maxconn 500 server ANID2 10.0.1.4:8888 check inter 3000 rise 2 fall 3 maxconn 500 listen health 0.0.0.0:9999 mode http balance roundrobin stats uri /haproxy-status 

我通过让客户绕过它直接到一个单一的应用程序服务器,没有超时,一切都很好,花花公子,证实HAProxy是问题。 只要我通过我们的两个haproxy服务器之一发送,随机断开发生在25-60秒之间的任何地方。

感谢您看看这个。 这是相当令人沮丧的,但我相信这是一个缺乏对HAProxy期望从我的客户的理解。

应该没有理由提前接近,我甚至不知道会发生什么。 您的超时设置为60秒,所以应该是60秒。

嗯等一下,你不是在运行速度快的虚拟机里运行haproxy吗? 在一些虚拟机中,时钟有时运行速度太快(超过正确速度的两倍),或者太慢,每分钟跳一次,这是一个问题。 Haproxy知道如何防止它可以检测到太久的停顿和时间跳跃,但显然它不能防止时钟运行速度太快而没有被系统报告。

如果你在虚拟机,你可以试试这个:

 $ while sleep 1; do date; done 

让这个运行一两分钟。 请自行检查是否以正确的速度运行。 自从我上次观察这个讨厌的问题以来已经有一段时间了,但这并不意味着它不会再发生。

顺便说一句,你应该在你的TCP部分设置“ option tcplog ”并检查日志。 如果从haproxy的angular度来看,你会看到那里,这是一个超时,客户端或服务器中止,并在多长时间后。

由于时间是可变的,你已经确定后端不负责任,它不可能是一个超时设置。

奇怪的是,这将导致我的解决scheme,可能是服务正在重新启动。

如果在cron上重新启动HAProxy(例如monit – 每60秒会轮询一次),那么这可能意味着一个会话在终止之前会持续60秒,或者更短。

仔细检查你的HAProxy的正常运行时间,如果它总是在一分钟左右 – 这是你的答案。

另外,也许值得从HAProxy中查看统计信息,以确保您没有遇到任何硬性会话限制,从而导致备用超时被触发。 如果队列中已经存在小于maxqueue请求,则对于timeout queue秒数,如果在超时之后没有发现不饱和服务器,则请求将被丢弃。

你可以testing这个:

 defaults timeout client 60000 option http-server-close 

而不是clitimeout

https://code.google.com/p/haproxy-docs/wiki/http_server_close

试试这个,我已经解决了这个问题。

 listen mysql-slaves bind 0.0.0.0:3306 mode tcp maxconn 20000 option mysql-check user haproxy balance roundrobin contimeout 5000 clitimeout 50000 srvtimeout 50000 ....