【问题标题】:How to stop a program in production safely如何安全地停止生产中的程序
【发布时间】:2018-01-31 13:18:53
【问题描述】:

我们有多台机器作为“服务器”运行。在他们身上,他们有一个程序来监听来自不同客户的请求。

在持续部署过程的一部分中,更新服务器程序可能会导致未完成的业务被终止。这是不可取的。我正在寻找一种方法来从一个节点排出工作,以便我们可以在另一个节点获得负载时更新它。

至于代表我当前心态的更具体的问题:

你如何发送“信号”所以:

while True and no_signal:
    do_server_work()

如果我们需要升级它就停止。

对于我们的基础架构,我们有许多客户端向多个 RabbitMQ 节点发送请求,服务器会在这些节点中使用它们的队列。

编辑:在 linux 上,使用 python3

【问题讨论】:

  • 谁在编写这个程序?你被允许并且有能力改进它吗?
  • 是的,我可以做任何需要的事情。
  • 您正在就一个非常具体的问题提出一个非常抽象的问题。您能否添加澄清细节或限制,以便我们指导您找到答案?例如,RabbitMQ 被标记,并具有“取消消费者”功能,但不清楚这对您有什么帮助,甚至是否有帮助。
  • 嗯,它之所以抽象是有原因的。我正在寻找不同的方法。取消消费者是我从 RabbitMQ 不知道的。这可能是一个很好的答案。我不需要实际的代码。

标签: linux python-3.x server rabbitmq continuous-deployment


【解决方案1】:

(我猜你是在 Linux 上,或者至少在 POSIX 机器上)

对于编写良好的服务器程序,您应该向它们发送一个SIGTERM 信号(有关详细信息,请参阅signal(7))以温和地终止它们,并且它们应该显式地 (并且巧妙地)处理该信号。一种常见的方法是使用kill(1) 程序(或底层的kill(2) 系统调用)。

编写糟糕的服务器程序可能无法按应有的方式处理SIGTERM。然后(几秒钟后)您可能需要使用 SIGKILL 杀死它们,但这可能会使它们(或它们的文件)处于某种不一致的状态,因为无法捕获 SIGKILL

一些服务器程序被记录为表现不同。例如,他们可能会使用其他一些inter-process communication 设施来要求温和地终止。

正确处理SIGTERM 是一个广泛使用的约定(但如果您正在编写处理它的服务器,请阅读signal-safety(7))。有些服务器可能有不同的。

顺便说一句,在 C 级别编写安全信号处理程序(仔细阅读signal-safety(7))有几个技巧。一种是拥有一个由信号处理程序设置的全局volatile sig_atomic_t 变量,并在您的代码(可能在您的event loops)中定期 进行测试。另一种方法是设置(在初始化时,使用pipe(2))一个pipe(7) 给自己,让你的信号处理程序write(2) 一个或几个字节(这是合法的,因为write(2) 是一个异步信号-safe 函数)和poll(2)read(2) 事件循环中的管道。后面的技巧在 Qt 中很常见,例如 documented

可能,Python 使用第一个技巧或类似的方法处理signals(可能与其臭名昭著的GIL 有关)。既然是free software,你可以研究一下它的源码(现在懒得做)。

【讨论】:

  • 是的,我正试图弄清楚如何捕获从 SIGTERM 引发的异常,以便即使它随时出现,我也可以完成工作。好点子,我正在研究这种方法。
  • SIGTERM 不是 例外,而是signal。异常要么在硬件级别(例如页面错误、特权指令、被零除),要么在语言运行时(这是“异常”一词的两种不同含义)。
  • 我指的是 Python 在程序执行期间处理 Ctrl+C 的方法。你说的对。我正在阅读有关信号以及如何实现它们的信息。这似乎是一个不错的计划。
  • Ctrl-C通常发送SIGINT,而不是SIGTERM
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多