Symfony Messenger 工作人员在 运行 处于监督之下时不会停止

Symfony messenger workers do not stop when running under supervisor

我遇到了 Symfony Messenger 组件的奇怪行为。我是按照documentation and I am issuing a messenger:stop-workers signal on each deploy as instructed here设置的。然而,我们的系统出现了一个错误,我追溯到 Messenger 工作人员使用旧版本代码的事实。

经过更多调查,这就是我们设置中发生的情况:

supervisor-managed worker 的处理时间限制为 1 小时,之后它们将停止并重新启动。我可以在 supervisord.log 中看到它运行良好。每小时都有关于进程停止和启动的日志条目。但是他们没有任何关于停止 messenger:stop-workers 命令的事情。

我正在寻找关于为什么会发生这种情况的想法。我看了worker的实现,关机信号是通过缓存发送的,但是我没有发现我们的配置有什么问题。

我 运行 遇到了类似的问题。

如您所见,为了强制停止其余消费者,该命令使用了缓存池。在我的例子中(也可能是你的),是存储在 /your_symfony_app/var/cache/{env}/pools

中的文件系统池

因此,如果您使用 Deployer 或任何其他部署系统来替换每个新部署的符号 link,您需要在文件夹 中执行命令 messenger:stop-workers你之前的版本.

另一种选择是配置一个由所有版本共享的缓存池,例如 memcached 或 redis。

就我而言,使用 Deployer(软件仍在开发中)我已经能够通过声明这样的任务并将其放入部署主任务中来解决它:

task('messenger:stop', function () {
    if (has('previous_release')) {
        run('{{bin/php}} {{previous_release}}/bin/console messenger:stop-workers');
    }
})->desc('Stop workers');

在我们等待更好的解决方案时,这里有一个解决此问题的方法。

只有当您的 Symfony Messenger 支持此处提交的 --failure-limit 选项时,您才能使用此解决方法: https://github.com/symfony/symfony/pull/35453/commits/ea79206470ac3b71520a35129d36ca0d11ce4a09

  1. 通过主管启动 Messenger 总是有一个最大失败: php bin/console messenger:consume async --failure-limit=1

  2. 在您的代码库中定义一个消息 RestartMessenger 和相应的处理程序 RestartMessengerHandler,它只是抛出一个异常,例如 MessengerNeedsToBeRestartedException

  3. 创建一个名为 app:messenger-restart-request 的 Symfony 命令,用于调度 RestartMessenger

  4. 在您的部署脚本(bash、Ansible 或其他)中添加作为最后一步:php bin/console app:messenger-restart-request。这将引发异常,导致 Messenger 重新启动,因为 --failure-limit=1