3

为了好玩,我一直在尝试用 python 编写负载均衡器,并试图找出最好的(正确的?)方法来测试端口是否可用并且远程主机是否仍然存在。

我发现,一旦连接,就很难判断远程主机何时关闭。我已经打开了保持活动状态,但是即使在设置了各种 TCP_KEEPALIVE 之后,它也无法在一分钟内识别出故障连接(我意识到轮询的频率超过一分钟可能有点过分了,但可以说我想这样做)选择最低。

当我使用非阻塞套接字时,我注意到 recv() 从活动套接字读取时会返回错误(“资源暂时不可用”),但从死套接字读取时会返回“”(发送和接收为 0字节,这可能是原因?)。不过,这似乎是一种奇怪的测试它是否已连接的方法,并且发送一些数据之后无法判断连接是否死亡。

除了每次检查都连接/断开连接之外,我还能做些什么吗?我可以手动发送 tcp keepalive,还是可以建立一个较低级别的连接,让我在不发送远程服务器可能处理的真实数据的情况下测试连接?

4

5 回答 5

2

我建议不要让您的(单个)测试套接字保持连接 - 每次需要轮询时都建立一个新连接。我见过的每个负载均衡器/服务器可用性系统都使用这种方法而不是持久连接。

如果远程服务器在合理的时间内(例如 10 秒)没有响应,则将其标记为“关闭”。使用计时器和信号而不是函数响应代码来处理该超时。

于 2009-04-21T07:20:07.373 回答
1

“很难判断远程主机何时关闭”

正确的。这是 TCP 的一个特性。TCP 的重点是在端口之间建立持久的连接。理论上,应用程序可以通过 TCP 断开并重新连接到端口(套接字库对此没有提供很多支持,但它是 TCP 协议的一部分)。

于 2009-04-21T15:33:33.630 回答
0

ping 就是为此目的而发明的

您也可以将格式错误的 TCP 数据包发送到您的目的地。例如,在 TCP 标头中有一个用于确认传输结束的标志,即 FIN 消息。如果您发送带有 ACK 和 FIN 的消息,远程主机应该会抱怨返回数据包,您将能够评估往返时间。

于 2009-04-21T07:16:34.200 回答
0

理论上可以向keepalive数据包发送垃圾邮件。但是要将其设置为非常低的间隔,您可能需要深入挖掘原始套接字。此外,如果它来得太快,您的主机可能会忽略它。

检查主机是否在 TCP 连接中处于活动状态的最佳方法是发送数据,然后等待 ACK 数据包。如果 ACK 包到达,SEND 函数将返回非零值。

于 2009-04-21T07:24:03.963 回答
0

您可以将Bash 伪设备文件用于具有特定 I/O 端口的 TCP/UDP 连接,例如:

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) 的示例规则:

# Verify host.
check host example with address example.com
  if failed
    port 80
    protocol http
  then alert
于 2016-02-11T11:43:34.260 回答