如果使用Python RQ,更新worker的步骤如下
首先
在Python中,有一个可以利用队列实现后台处理的库,叫做rq。
这个库利用Redis作为消息队列,通过启动任意数量的worker进程来实现后台处理。无需使用Rabbit MQ或Kafka等专门的消息队列中间件,就可以构建小规模的后台处理系统。
试用这个来进行正式更新,并调查了如何进行安全更新的结果,发现了一些小诀窍,所以将调查结果和步骤记录下来。
问题点
当更新应用程序(Worker)时,如果不在所有Worker都停止运行的情况下进行更新,会导致作业仍处于处理中状态。因此,在更新之前需要先设置标志,以使每个Worker不再执行更多新作业,并在所有任务完成后进行更新。
为了解决这个问题,引入了挂起模式。通过提供的 CLI 工具 `rq suspend`,可以让每个工作者暂时停止接收新作业。当然,正如下面的示例所示,正在工作者中执行的作业不会停止。
$ rq suspend
Suspending workers. No new jobs will be started. But current jobs will be completed
从这个行为来看,用户可能认为“因为挂起状态,不会接收到新的工作”,但实际上并不是这样直观的行为。
在空闲状态下,没有执行任何工作的工作者将持续接收新的工作。并且,完成一个工作后将进入挂起状态,不再接收新的工作。
这个问题已经总结在以下的问题(Issue)中。
策略解决
在上述问题中,有几种处理方法,但在更新时执行适当数量的无操作作业(守卫)是最简单的。以下是在bash中的判断示例。
# idle 状態のワーカーがいるかどうかを確認して、件数分番兵ジョブを登録する
$ rq info | grep idle | wc -l
# 全てのワーカーが suspend 状態であればワーカーを再起動して更新を反映
# なお suspend 状態で起動したワーカーは最初から状態が suspend になっている
$ rq info | grep suspend | wc -l
# 再起動後は suspend を解除
$ rq resume