升级服务器可执行文件而不会丢失用户的连接

时间:2015-11-11 17:15:57

标签: c network-programming

我需要开发一种机制,将生产环境中正在运行的守护进程升级到新版本,而不会丢失客户端(TCP)连接。类似于nginx将其升级到新版本时所做的事情。我需要这个以删除错误或发布次要版本更改,这可能是一天一次。该守护进程是在C for Linux平台上开发的。

升级过程如下:

  1. new_daemon将从命令行运行,指定old_daemon的进程ID
  2. new_daemon将通过套接字连接到旧守护进程,以发送/接收数据和消息。
  3. new_daemon会向old_daemon发送一条消息,以停止侦听用于接收客户端连接的 PORT 。确认监听服务被扣留后,new_daemon将开始侦听 PORT
  4. new_daemon会将消息发送到old_daemon,以发送用户连接的当前打开的文件描述符。使用系统调用sendmsg(),old_daemon将传递new_daemon它为内核分配的所有资源,不仅是连接,还包括所有打开的文件。
  5. new_daemon会将消息发送到old_daemon以传递所有全局内存变量,而old_daemon将通过两个进程之间的套接字连接发送它。
  6. 这个过程非常复杂,所以我想问一下是否有人可以建议一个更好的流程,或者有一些方法可以轻松地做到这一点?目标是在升级过程中减少停机时间。

    TIA

2 个答案:

答案 0 :(得分:1)

另一种方法是强制old_daemon fork()/exec() new_daemon并立即停止接受。 new_daemon将自动继承侦听套接字,现有连接和打开文件(除非它们fcntlFD_CLOEXEC)。

那就是说,我认为没有一种干净的方法来交出不完整的工作(据我所知,第4步和第5步试图完成)。如果可能,请让old_daemon完成它们。

答案 1 :(得分:0)

另一种方法是将大部分恶魔写为共享库,并使用dlopen将新功能链接到正在运行的进程中。这意味着某些部分无法更改,您可能会遇到并发问题,但它不再需要IPC。