为了好玩,我一直在玩python中编写负载均衡器,并且一直试图找出最好的(正确的?)方法来测试端口是否可用且远程主机仍在那里。
我发现,一旦连接,就很难判断远程主机何时出现故障。我已经开始活着,但是不能让它早点识别掉连接(我知道轮询的时间可能超过一分钟可能是矫枉过正,但是我想说)我甚至在设置了各种TCP_KEEPALIVE之后他们最低的选择。
当我使用非阻塞套接字时,我注意到当从活动套接字读取时,recv()将返回错误(“资源暂时不可用”),但在从死亡套接字读取时返回“”(发送和recv为0字节,这可能是原因?)。这似乎是一种测试连接的奇怪方法,但是无法判断连接是否已经死亡,而在发送一些数据之后。
除了为每张支票连接/断开连接外,我能做些什么吗?我可以手动发送tcp keepalive,还是可以建立一个较低级别的连接,让我测试连接而不发送远程服务器可能处理的实际数据?
答案 0 :(得分:2)
我建议不要让您的(单个)测试套接字连接 - 每次需要轮询时建立一个新连接。我见过的每个负载均衡器/服务器可用性系统都使用此方法而不是持久连接。
如果远程服务器在合理的时间内没有响应(例如10秒),请将其标记为“关闭”。使用定时器和信号而不是功能响应代码来处理该超时。
答案 1 :(得分:1)
“很难判断远程主机何时出现故障”
正确。这是TCP的一个特性。 TCP的重点是在端口之间建立持久的连接。从理论上讲,应用程序可以通过TCP丢弃并重新连接到端口(套接字库不会为此提供很多支持,但它是TCP协议的一部分)。
答案 2 :(得分:0)
您也可以将格式错误的TCP数据包发送到目的地。例如,在TCP标头中有一个标志,用于确认传输结束,即FIN消息。如果您发送带有ACK和FIN的消息,远程主机应该使用返回数据包进行投诉,您将能够评估往返时间。
答案 3 :(得分:0)
理论上可以发送keepalive数据包。但要将其设置为非常低的间隔,您可能需要挖掘原始套接字。此外,如果主机进入太快,您的主机可能会忽略它。
检查主机在TCP连接中是否处于活动状态的最佳方法是发送数据,然后等待ACK数据包。如果ACK数据包到达,SEND功能将返回非零。
答案 4 :(得分:0)
您可以使用Bash pseudo-device files与特定I / O端口建立TCP / UDP连接,例如:
printf "" > /dev/tcp/example.com/80 && echo Works
这会打开连接,但不会发送任何内容。你可以通过以下方式测试它:
nc -vl 1234 &
printf "" > /dev/tcp/localhost/1234
对于简单监控,请使用cron with above命令或使用watch
:
watch bash -c 'echo > /dev/tcp/localhost/1234 && echo Works || echo FAIL'
然而,建议使用专为Monit,Nagios等设计的特定工具。
以下是使用Monit(monit
)的示例规则:
# Verify host.
check host example with address example.com
if failed
port 80
protocol http
then alert