【发布时间】:2018-11-01 20:28:55
【问题描述】:
在 TCP/IP 端口中有一个程序监听和应答请求(专有二进制协议)。但是这个程序需要更新,所以需要重新启动它才能继续在同一个端口上工作。
根据其协议,所有当前连接都可以关闭,因为所有客户端在关闭后都会立即重新建立新连接,但新连接应保留(但不拒绝)直到程序重新启动(对于少数秒),怎么办?
因此,一旦它再次运行,给定端口上的所有保留连接都可以被释放以到达侦听套接字。
让我们想象以下步骤:
- 一个服务器程序正在运行并监听给定的端口,让我们 说港口 A。
- 它要求外部资源(如操作系统或任何第三方模块)保留所有到达端口 A 的连接。
- 它会关闭当前与端口 A 建立的所有当前连接 - 这可能需要一些时间(可能需要几分钟,因为它将首先完成所有请求的服务)
- 它已重新启动,一个全新的可执行文件开始运行并开始侦听端口 A。
- 它要求外部资源释放所有保留的连接,以便它们现在可以到达端口 A,该端口现在已准备好接收连接。
第 2 步和第 4 步只是假设。
【问题讨论】:
-
我知道的唯一方法是将监听套接字委托给一个单独的进程。但是,如果该过程也需要更新,那么您又回到了同样的问题。第 22 条军规。不值得尝试解决。只需让服务器杀死其活动客户端并关闭其侦听端口,然后在更新完成后重新打开该端口即可。在更新期间尝试重新连接的客户端将无法连接。应该对它们进行合理的编码,以 X 间隔重试 N 次,直到重新连接,并在 N 次尝试失败后超时并放弃。
-
您最好在负载均衡器后面拥有多个程序实例。这样你就可以从一个实例中释放连接,并在它空闲时重新启动它。
-
@dbush:对不起,我没有列出在那种情况下我没有多个主机(计算机),但是有没有办法像负载均衡器那样切换连接,但是在进程之间(在同一个系统中)?
-
负载均衡器不一定需要多个主机。让 LB 在一个端口上运行,应用程序的每个实例在不同的端口上运行。
-
@RemyLebeau:在非 Windows 系统上,可以通过本地 Unix 域套接字使用 SCM_RIGHTS 辅助有效负载,在进程之间传输侦听套接字描述符。所以,助手进程只需要在更新期间存活,之后就可以退出。事实上,我建议(在下面回答)让服务自己创建该子进程。不过,我猜 Windows 服务编写者只能使用负载均衡器。
标签: c sockets serversocket