【问题标题】:Permanent TCP connection for administration use用于管理的永久 TCP 连接
【发布时间】:2014-06-12 13:52:53
【问题描述】:
我面临以下情况:
我有几台设备(运行 ARCH Linux 的嵌入式设备),我希望随时拥有对每台设备的管理访问权限。问题是设备位于 NAT 之后,因此无法建立从服务器到设备的连接。我怎么能做到这一点?
我想我可以编写一个在设备上运行的简单服务,该服务在启动时打开与服务器的连接。此 TCP 连接保持打开状态,可从服务器用于管理设备。但是长时间保持 TCP 连接打开是个好主意吗?如果我有很多设备,例如 1000 个,我会在服务器端出现 1000 个打开的 TCP 连接的问题吗?
有没有别的办法?
非常感谢!
【问题讨论】:
标签:
linux
sockets
tcp
connection
【解决方案1】:
但是长时间保持 TCP 连接打开是个好主意吗?
这不一定是个坏主意;尽管在实践中连接会不时失败(例如,由于网络重新配置、临时网络中断等),但您的客户端应该包含在发生这种情况时自动重新连接的逻辑。另请注意,当完全空闲的 TCP 连接不再具有连接性时,TCP 通常不会检测到它,因此为了避免实际未连接的“僵尸连接”,您可能需要启用 SO_KEEPALIVE,或者让您的客户端和/或者服务器在套接字上发送(非常偶然的)一些虚拟数据,只是为了让 TCP 堆栈检查套接字上是否仍然存在连接。
如果我有很多设备,例如 1000 个,我会在服务器端有 1000 个打开的 TCP 连接出现问题吗?
缩放绝对是您需要考虑的问题。例如, select() 通常被实现为只处理固定数量的连接(通常为 1024),或者如果您的服务器使用每个连接的线程模型,您会发现具有 1000 多个线程的进程是效率不高。查看c10k problem article,了解有关各种方法的许多有趣细节,以及它们如何扩大规模(或不扩大规模)。
还有其他方法吗?
如果您不需要立即访问客户,则可以随时让他们定期检查(例如每 5 分钟一次);或者您可以让他们偶尔向服务器发送一个 UDP 数据包,而不是一直保持 TCP 连接,只是为了让服务器知道他们的存在,并让服务器以某种方式向他们指示(例如,通过更新知名网页客户端不时检查)何时希望其中一个打开完整的 TCP 连接。或者也许只是使用多台服务器来分担负载......
【解决方案2】:
我知道的唯一限制是iptables 代码中的状态跟踪。如果您使用它,请检查两边的net.ipv4.netfilter.ip_conntrack_max 的值,以确保您有足够的空间用于其他活动。
如果您在调用connect() 之前设置了套接字选项SO_KEEPALIVE,内核将发送TCP keepalives 以确保远端仍然存在。这意味着在重新启动时连接不会永远存在。