套接字 – 如何以最短的停机时间移交TCP侦听套接字?

虽然这个问题被标记为EventMachine,但任何语言的通用BSD套接字解决方案也非常受欢迎.

一些背景:

我有一个应用程序侦听TCP套接字.它使用常规的System V样式初始化脚本启动和关闭.

我的问题是它在准备好为TCP套接字服务之前需要一些时间来启动.它不会太长,也许只有5秒,但是在工作日需要重启时,这个时间太长了5秒.现有连接保持打开并正常完成也很重要.

重新启动应用程序的原因是补丁,升级等.不幸的是,我发现自己处于一种状态,每隔一段时间,我就需要在生产中做这种事情.

问题是:

我正在寻找一种方法来完成从一个进程到另一个进程的TCP侦听套接字的整齐移交,因此只能获得一秒钟的停机时间.我希望现有的连接/套接字保持打开状态并在旧进程中完成处理,而新进程开始为新连接提供服务.

是否有一些经过验证的方法使用BSD套接字执行此操作? (EventMachine解决方案的奖励积分.)

是否有可能实现这一点的开源库,我可以按原样使用,还是用作参考? (同样,非Ruby和非EventMachine解决方案也很受欢迎!)

最佳答案
有几种方法可以在没有停机的情况下执行此操作,并对服务器程序进行适当的修改.

一种是在服务器本身中实现重启能力,例如在接收到某个信号或其他消息时.然后程序将执行其新版本,向其传递监听套接字的文件描述符号,例如作为一个论点.此套接字将清除FD_CLOEXEC标志(默认值),以便继承它.由于其他套接字将继续由原始进程提供服务而不应传递给新进程,因此应在那些套接字上设置标志.使用fcntl().在分叉并执行新进程之后,原始进程可以继续并关闭侦听套接字而不会中断服务,因为新进程现在正在侦听该套接字.

另一种方法是,如果您不希望旧服务器必须分叉并执行新服务器本身,则使用Unix-domain socket在旧服务器进程和新服务器进程之间进行通信.新的服务器进程可以在启动时在文件系统中的已知位置检查这样的套接字.如果存在,新服务器将连接到此套接字并请求旧服务器使用SCM_RIGHTS将其侦听套接字作为辅助数据传输.这方面的一个例子是在cmsg(3)年底给出的.

转载注明原文:套接字 – 如何以最短的停机时间移交TCP侦听套接字? - 代码日志