代码之家  ›  专栏  ›  技术社区  ›  Stéphan Kochen

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

  •  8
  • Stéphan Kochen  · 技术社区  · 14 年前

    当这个问题被标记为EventMachine时, 任何语言的通用BSD插座解决方案也非常受欢迎。


    一些背景:

    我有一个应用程序正在监听TCP套接字。它是用一个常规的SystemV样式的init脚本启动和关闭的。

    我的问题是,它需要一段时间来启动,然后才能为TCP套接字提供服务。时间不太长,可能只有5秒,但当需要在工作日重新启动时,时间太长了5秒。现有连接保持打开并正常完成也是至关重要的。

    重新启动应用程序的原因包括修补程序、升级等。不幸的是,我发现自己处于这样的位置,每隔一段时间,我都需要在生产中做这种事情。


    问题:

    我正在寻找一种方法,从一个进程到另一个进程,对TCP侦听套接字进行一次整洁的移交,结果只得到一秒的停机时间。我希望现有的连接/套接字保持开放状态,并在旧进程中完成处理,而新进程将开始服务于新的康涅狄诺。

    是否有一些行之有效的方法来使用BSD套接字?(EventMachine解决方案的奖励点数。)

    有没有可能存在实现这一点的开放源码库,我可以按原样使用,或者作为参考使用? (再次感谢非Ruby和非EventMachine解决方案!)

    2 回复  |  直到 14 年前
        1
  •  8
  •   mark4o    14 年前

    有几种方法可以在不停机的情况下完成这项工作,并对服务器程序进行适当的修改。

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

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

        2
  •  1
  •   Glyph    14 年前

    让·保罗·卡尔德龙写了一篇 detailed presentation 2004年,关于使用Twisted解决您的问题的整体解决方案,包括套接字迁移和其他问题。