题
为了好玩,我一直在玩弄周围用Python写一个负载均衡器,并已试图找出最好的(正确吗?)的方式来测试,如果一个端口可与远程主机仍然存在。
我发现,一旦连接,就很难在远程主机出现故障判断。我转身继续活着,但不能让它认识到一个被击落的连接超过一分钟快(我往往比一分钟可能是矫枉过正实现轮询,但可以说,我想),甚至设置各种TCP_KEEPALIVE后选项,以它们的最低
当我使用非阻塞套接字,我注意到一个的recv()将返回一个错误(“资源暂时不可用”),当它从现场插座读取,但返回“”从一个死一个读取时(发送和0字节,这可能是原因的recv?)。这似乎是一个奇怪的方法来测试它连接,虽然,使得它无法告诉我们,如果连死了,但的之后的发送一些数据。
除了连接/断开每一个检查,是有什么我可以做什么?我可以手动发送一个TCP保活,或者我可以建立一个较低的水平连接,这将让我测试连接不发送真实数据的远程服务器将可能处理?
解决方案
我建议你不会离开你的连接(单)测试插座 - 建立新的连接每次需要轮询时间。我见过的每一个负载均衡器/服务器可用性系统中使用这种方法,而不是一个永久连接。
如果远程服务器未在合理的时间量(例如10秒)内的反应将其标记为“下”。使用定时器和信号,而不是函数的响应代码,以处理超时。
其他提示
“则变得难以在远程主机下降到告诉”
正确。这是TCP的功能。 TCP的全部意义就是有端口之间的连接持久。理论上一个应用程序可以删除并重新连接到通过TCP端口(插座库不提供大量的这种支持,但它是TCP协议的一部分)。
平被发明用于这一目的
你也可能能够畸形的TCP数据包发送到你的目的地。例如,在TCP报头存在用于acknowleging传输的结束,其FIN消息的标志。如果您发送带有ACK和FIN远程主机应该用返回的数据包抱怨,你就能够评估往返时间。
它在理论上是可能的垃圾邮件保活分组。但是,将其设置为非常低的区间,则可能需要深入挖掘原始套接字。此外,您的主机可能会忽略它,如果它的速度太快到来。
要检查的最佳方式如果主机是在TCP连接活跃是发送数据,并等待ACK分组。如果ACK包到达时,SEND函数会返回一个非零值。
可以使用击伪设备文件用于TCP / UDP与特定的I / O端口连接,例如:
printf "" > /dev/tcp/example.com/80 && echo Works
这将打开连接,但不会发送任何东西。可以通过测试:
nc -vl 1234 &
printf "" > /dev/tcp/localhost/1234
有关简单的监测使用cron与上述命令或使用watch
:
watch bash -c 'echo > /dev/tcp/localhost/1234 && echo Works || echo FAIL'
然而,推荐使用,其被设计用于特定的工具,如monit的,Nagios的等
monit的
下面是使用monit的(monit
)示例规则:
# Verify host.
check host example with address example.com
if failed
port 80
protocol http
then alert