如何以最少的停机时间来交接TCP侦听套接字? [英] How to hand-over a TCP listening socket with minimal downtime?

查看:90
本文介绍了如何以最少的停机时间来交接TCP侦听套接字?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

虽然这个问题被标记为EventMachine,但也很感谢使用任何语言的通用BSD套接字解决方案.

While this question is tagged EventMachine, generic BSD-socket solutions in any language are much appreciated too.

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

I have an application listening on a TCP socket. It is started and shut down with a regular System V style init script.

我的问题是,准备好服务TCP套接字之前需要花费一些时间来启动.时间不太长,也许只有5秒,但是当需要在工作日内执行重新启动时,那太长了5秒.现有连接保持打开状态并正常完成也是至关重要的.

My problem is that it needs some time to start up before it is ready to service the TCP socket. It's not too long, perhaps only 5 seconds, but that's 5 seconds too long when a restart needs to be performed during a workday. It's also crucial that existing connections remain open and are finished normally.

重新启动应用程序的原因是补丁,升级等.不幸的是,我发现自己偶尔需要在生产中做这种事情.

Reasons for a restart of the application are patches, upgrades, and the like. I unfortunately find myself in the position that, every once in a while, I need to do this kind of thing in production.

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

I'm looking for a way to do a neat hand-over of the TCP listening socket, from one process to another, and as a result get only a split second of downtime. I'd like existing connections / sockets to remain open and finish processing in the old process, while the new process starts servicing new connectinos.

是否有使用BSD套接字进行此操作的成熟方法? (EventMachine解决方案的奖励积分.)

Is there some proven method of doing this using BSD-sockets? (Bonus points for an EventMachine solution.)

也许有开源库可以实现此功能,我可以原样使用它,也可以用作参考? (同样也欢迎使用非Ruby和非EventMachine解决方案!)

Are there perhaps open-source libraries out there implementing this, that I can use as is, or use as a reference? (Again, non-Ruby and non-EventMachine solutions are appreciated too!)

推荐答案

有几种方法可以在不停机的情况下对服务器程序进行适当的修改.

There are a couple of ways to do this with no downtime, with appropriate modifications to the server program.

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

One is to implement a restart capability in the server itself, for example upon receipt of a certain signal or other message. The program would then exec its new version, passing it the file descriptor number of the listening socket e.g. as an argument. This socket would have the FD_CLOEXEC flag clear (the default) so that it would be inherited. Since the other sockets will continue to be serviced by the original process and should not be passed on to the new process, the flag should be set on those e.g. using fcntl(). After forking and execing the new process, the original process can go ahead and close the listening socket without any interruption to the service, since the new process is now listening on that socket.

如果您不希望旧服务器必须派生并执行新服务器本身,则另一种方法是使用 cmsg的末尾给出了一个示例. (3).

An alternative method, if you do not want the old server to have to fork and exec the new server itself, would be to use a Unix-domain socket to communicate between the old and new server process. A new server process could check for such a socket in a well-known location in the file system when it is starting. If present, the new server would connect to this socket and request that the old server transfer its listening socket as ancillary data using SCM_RIGHTS. An example of this is given at the end of cmsg(3).

这篇关于如何以最少的停机时间来交接TCP侦听套接字?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆