在应用部署时重启队列任务处理进程
应用部署时,需要重启队列处理器进程告知代码变动。
通过 CLI 重启
可以在部署脚本中,代码拉取更新后运行重启命令:
该命令会向所有正在运行的处理器进程发送信号,告知它们在完成手头工作后退出,这就是所谓的「优雅重启」。
以 Laravel Forge 部署脚本为例,完整的操作指令如下:
php-fpm
重启后,应用访问者可以访问基于最新代码的应用,不过队列处理器进程中加载的代码还是老的,重启后,就都是最新的了。
如果使用的是 Envoyer,可以在「新发布」动作之后的部署钩子中运行 queue:restart
命令。
通过 Supervisor 重启
如果是通过 Supervisor 管理的队列任务处理器进程,可以通过 supervisorctl
命令重启:
重启 Horizon
和队列处理器进程一样,需要告知 Horizon 的 Supervisor 主进程停止所有正在运行的处理器进程:
不过为了确保任务不被打断,需要确保满足以下条件:
- Horizon Supervisor
timeout
配置值大于最耗时的队列任务运行时间; - 队列任务指定的
timeout
小于 Horizon supervisor 配置的超时时间; - 如果你在使用 Supervisor 进程管理器监控 Horizon 进程,确保
stopwaitsecs
大于最耗时队列任务运行时间。
按照上述条件完成配置后,Supervisor 会等待 Horizon 进程停止,并且不会在 stopwaitsecs
之后强制停止。
处理数据库迁移
发送重启信号给处理器进程时,其中一些不会立即重启,因为需要等到手头处理完成后才会退出。
如果部署的代码包含修改数据库结构的迁移,处理器进程仍然使用的是老代码,则可能在处理中途报错,因为数据库结构变了,可能原来的字段不存在了。
要避免这个问题,需要在部署前告知所有处理器进程退出,并等待数据库迁移完毕后再启动。这可以通过在部署脚本中调用 supervisorctl stop
来实现,该命令会阻塞后续脚本执行,直到所有处理器进程优雅退出:
部署用户需要拥有执行
sudo supervisor
的权限。
当然了,如果处理器进程很多或者某些队列任务耗时很长,这个 supervisorctl stop
需要很久才能执行完毕,阻塞部署流程。
如果没有修改表结构的数据库迁移,你也不想退出处理器进程,建议你不要把 supervisorctl stop
命令放到部署脚本里,只有在存在修改表结构的数据库迁移时才提供。
还可以将 supervisorctl stop
和 supervisorctl start
从部署脚本中拆出来单独执行。
2 Comments
图片 地址挂了, 个人收藏也坏了
图片都已经恢复正常了