Symfony信使工人在监督下运行时不会停止

v9tzhpje  于 2023-01-21  发布在  其他
关注(0)|答案(4)|浏览(116)

我遇到了Symfony Messenger组件的一个奇怪行为。我根据documentation设置了它,并按照此处的指示在每次部署时发出messenger:stop-workers信号。然而,我们的系统中出现了一个bug,我追溯到Messenger工作人员正在使用旧版本的代码。
经过进一步的研究,我们的设置如下所示:

  • 工作进程正在运行,由超级用户管理。
  • 为了调试这个特定的例子,我在终端app/console messenger:consume --env=prod -vv async中启动了一个新的工作线程,看看会发生什么
  • 我发出停止命令app/console messenger:stop-workers --env=prod
  • 我现在希望两个工作线程都停止(并且监督线程将重新启动它正在处理的线程),但是,这并没有发生,“调试”工作线程确实停止了,但是在监督线程下运行的线程什么也不做。

管理者管理的工作进程被限制在1小时的进程时间内,之后它们将停止并重新启动。我可以在supervisord.log中看到这一点。每个小时都有关于进程停止和启动的日志条目。但是没有任何关于它们从messenger:stop-workers命令停止的内容。
我正在寻找为什么会发生这种情况的想法。我读了工作者的实现,关闭信号是通过缓存发送的,但我没有发现它的配置有任何问题。

sgtfey8w

sgtfey8w1#

我也遇到过类似的问题。
如您所见,为了强制停止其他使用者,该命令使用了缓存池,在我的示例中(可能您的示例也是如此),是存储在/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');
lkaoscv7

lkaoscv72#

在我们等待更好的解决方案时,这里有一个解决这个问题的方法。
仅当Symfony Messenger支持此处提交的--failure-limit选项时,才可以使用此解决方法:https://github.com/symfony/symfony/pull/35453/commits/ea79206470ac3b71520a35129d36ca0d11ce4a09
1.通过主管启动Messenger,最多失败一次:php bin/console messenger:consume async --failure-limit=1
1.在代码库中定义消息RestartMessenger和相应的处理程序RestartMessengerHandler,该处理程序只抛出异常,如MessengerNeedsToBeRestartedException
1.创建一个名为app:messenger-restart-request的Symfony命令,用于调度RestartMessenger
1.在您的部署脚本(bash、Ansible或其他)中,添加以下内容作为最后一步:php bin/console app:messenger-restart-request。这将引发异常,该异常将导致Messenger重新启动,因为--failure-limit=1

kb5ga3dv

kb5ga3dv3#

另一个选项是pkill,如果它可用并允许使用:

desc('Stop Messenger workers');
task('messenger:stop-workers', function (): void {
    run('pkill --uid {{remote_user}} --echo --full messenger:consume');
});
after('deploy:symlink', 'messenger:stop-workers');

这可靠地(并且仍然干净地)终止所有Messenger工作者,独立于任何版本。

  • --uid {{remote_user}}限制与SSH用户进程的匹配
  • --echo输出终止进程的名称和以前的PID
  • --full还包括用于匹配的命令参数
  • messenger:consume.../console messenger:consume <flags>命令行匹配

这里有几个假设:

  • 一个在host()上执行->set('remote_user', '...')以进行部署
  • Supervisord使用同一用户启动Symfony console messenger:consume进程
  • 每个用户在服务器上只有一个项目
f2uvfpb9

f2uvfpb94#

我在Ansistranoafter_cleanup_tasks.yaml文件中添加了以下任务:

- name: Stop running Symfony Messenger consumers
  shell:
    chdir: "{{ ansistrano_release_path.stdout }}/../../current"
    cmd: php bin/console messenger:stop-workers

相关问题