11

我正面临 Symfony Messenger 组件的奇怪行为。我根据文档进行设置,并按照此处messenger:stop-workers的说明在每次部署时发出信号。但是,我们的系统中出现了一个错误,我追溯到 Messenger 工作人员正在使用旧版本的代码这一事实。

经过进一步调查,这就是我们的设置中发生的情况:

  • 一个工人正在运行,由主管管理。
  • 只是为了调试这种特殊情况,我在终端app/console messenger:consume --env=prod -vv async中启动了一个新工作人员,看看会发生什么
  • 我发出停止命令app/console messenger:stop-workers --env=prod
  • 我现在希望这两个工人都会被停止(并且主管会重新启动它正在处理的那个)。但是,这不会发生。“调试”工作人员确实停止了,但在主管下运行的工作人员什么也不做。

主管管理的工作人员被限制为 1 小时的处理时间,之后它们将停止并重新启动。我可以看到supervisord.log这很好用。每小时都有关于进程停止和启动的日志条目。但是他们并没有停止messenger:stop-workers命令。

我正在寻找关于为什么会发生这种情况的想法。我阅读了工人的实现,并通过缓存发送了关闭信号,但我没有发现我们的配置有任何问题。

4

2 回答 2

9

我遇到了类似的问题。

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

因此,如果您使用 Deployer 或任何其他用每个新部署替换符号链接的部署系统,您需要在先前版本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');
于 2020-08-29T22:15:40.943 回答
1

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

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

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

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

  3. 创建一个名为app:messenger-restart-requestdispatch的 Symfony 命令RestartMessenger

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

于 2020-11-23T15:51:52.067 回答