在应用部署时重启队列任务处理进程


应用部署时,需要重启队列处理器进程告知代码变动。

通过 CLI 重启

可以在部署脚本中,代码拉取更新后运行重启命令:

-w590

该命令会向所有正在运行的处理器进程发送信号,告知它们在完成手头工作后退出,这就是所谓的「优雅重启」。

以 Laravel Forge 部署脚本为例,完整的操作指令如下:

-w670

php-fpm 重启后,应用访问者可以访问基于最新代码的应用,不过队列处理器进程中加载的代码还是老的,重启后,就都是最新的了。

如果使用的是 Envoyer,可以在「新发布」动作之后的部署钩子中运行 queue:restart 命令。

通过 Supervisor 重启

如果是通过 Supervisor 管理的队列任务处理器进程,可以通过 supervisorctl 命令重启:

-w652

重启 Horizon

和队列处理器进程一样,需要告知 Horizon 的 Supervisor 主进程停止所有正在运行的处理器进程:

-w633

不过为了确保任务不被打断,需要确保满足以下条件:

  1. Horizon Supervisor timeout 配置值大于最耗时的队列任务运行时间;
  2. 队列任务指定的 timeout 小于 Horizon supervisor 配置的超时时间;
  3. 如果你在使用 Supervisor 进程管理器监控 Horizon 进程,确保 stopwaitsecs 大于最耗时队列任务运行时间。

按照上述条件完成配置后,Supervisor 会等待 Horizon 进程停止,并且不会在 stopwaitsecs 之后强制停止。

处理数据库迁移

发送重启信号给处理器进程时,其中一些不会立即重启,因为需要等到手头处理完成后才会退出。

如果部署的代码包含修改数据库结构的迁移,处理器进程仍然使用的是老代码,则可能在处理中途报错,因为数据库结构变了,可能原来的字段不存在了。

要避免这个问题,需要在部署前告知所有处理器进程退出,并等待数据库迁移完毕后再启动。这可以通过在部署脚本中调用 supervisorctl stop 来实现,该命令会阻塞后续脚本执行,直到所有处理器进程优雅退出:

-w600

部署用户需要拥有执行 sudo supervisor 的权限。

当然了,如果处理器进程很多或者某些队列任务耗时很长,这个 supervisorctl stop 需要很久才能执行完毕,阻塞部署流程。

如果没有修改表结构的数据库迁移,你也不想退出处理器进程,建议你不要把 supervisorctl stop 命令放到部署脚本里,只有在存在修改表结构的数据库迁移时才提供。

还可以将 supervisorctl stopsupervisorctl start 从部署脚本中拆出来单独执行。


Vote Vote Cancel Collect Collect Cancel

<< 上一篇: 在生产环境管理队列任务的重试

>> 下一篇: 如何设计可靠的消息队列任务