虽然这个问题被标记为EventMachine,但任何语言的通用BSD套接字解决方案也非常受欢迎。
我有一个应用程序侦听TCP套接字。它使用常规的System V样式初始化脚本启动和关闭。
我的问题是它需要一些时间才能在准备好为TCP套接字提供服务之前启动。它不会太长,也许只有5秒,但是在工作日需要重启时,这个时间太长了5秒。现有连接保持打开并正常完成也很重要。
重新启动应用程序的原因是补丁,升级等。不幸的是,我发现自己处于这样一种状态:每隔一段时间,我就需要在生产中做这种事情。
我正在寻找一种方法来完成从一个进程到另一个进程的TCP侦听套接字的整齐移交,因此只能获得一秒钟的停机时间。我希望现有的连接/套接字保持打开状态并在旧进程中完成处理,而新进程开始为新的连接提供服务。
使用BSD套接字是否有一些经过验证的方法? (EventMachine解决方案的奖励积分。)
是否有可能实现此目的的开源库,我可以按原样使用,还是用作参考? (同样,非Ruby和非EventMachine解决方案也受到赞赏!)
答案 0 :(得分:8)
有几种方法可以在没有停机的情况下执行此操作,并对服务器程序进行适当的修改。
一种是在服务器本身中实现重启能力,例如在接收到某个信号或其他消息时。然后程序将执行其新版本,向其传递监听套接字的文件描述符号,例如作为一个论点。此套接字将清除FD_CLOEXEC
标志(默认值),以便继承它。由于其他套接字将继续由原始进程提供服务,并且不应传递给新进程,因此应在那些套接字上设置标志。使用fcntl()
。在分叉并执行新进程之后,原始进程可以继续并关闭侦听套接字而不会中断服务,因为新进程现在正在侦听该套接字。
另一种方法是,如果您不希望旧服务器必须分叉并执行新服务器本身,那么将使用Unix-domain socket在旧服务器进程和新服务器进程之间进行通信。新的服务器进程可以在文件系统启动时在文件系统中的已知位置检查这样的套接字。如果存在,新服务器将连接到此套接字并请求旧服务器使用SCM_RIGHTS将其侦听套接字作为辅助数据传输。 cmsg(3)的末尾给出了一个例子。
答案 1 :(得分:1)
Jean-Paul Calderone在2004年写了一篇关于使用Twisted解决问题的整体解决方案的detailed presentation,包括套接字迁移和其他问题。