Laravel配置Supervisor时如何实现order队列任务串行执行
实现order队列串行执行的Supervisor配置方案
原有配置的问题根源
当前配置下,8个worker进程全部同时监听email、order、notify三个队列,当order队列存在待处理任务时,所有空闲的worker都会争抢拉取任务,自然会出现多进程并发处理order任务的情况。单靠调整原配置里的numprocs参数,无法实现order队列严格串行、无并发的要求。
核心实现思路
将不同并发要求的队列拆分为独立的Supervisor程序块分别管理:
- 对email、notify这类可以支持并发处理的队列,分配多个worker进程提升处理效率
- 对order这类要求严格串行、禁止并发的队列,单独分配仅1个worker进程专门处理,从根源上避免多进程争抢同一队列任务的情况
具体配置示例
把原来单块的[program:laravel-worker]配置替换为两个独立的配置块,分别对应不同队列:
1. 通用并发队列的worker配置
这个配置负责处理可以并发执行的email、notify队列,保持原有的多进程能力:
[program:laravel-worker-general] process_name=%(program_name)s_%(process_num)02d command=php /app/artisan queue:work --queue=email,notify --tries=5 --sleep=3 autostart=true autorestart=true numprocs=7 redirect_stderr=true stdout_logfile=/app/worker-general.log stopwaitsecs=3600
2. order队列的专属worker配置
这个配置仅监听order队列,进程数固定为1,从机制上保证同一时间只会有1个进程处理order任务,天然实现串行执行的效果:
[program:laravel-worker-order] process_name=%(program_name)s command=php /app/artisan queue:work --queue=order --tries=5 --sleep=3 autostart=true autorestart=true numprocs=1 redirect_stderr=true stdout_logfile=/app/worker-order.log stopwaitsecs=3600
生效后的运行逻辑
- 通用队列的7个worker仅会拉取email、notify队列的任务,完全不会触碰order队列的任务,不会和order专属worker产生任务争抢
- order专属worker同一时间只会拉取1个order任务执行,等当前任务执行完成后,才会继续拉取队列里的下一个order任务,哪怕队列里堆积了多个待处理的ProcessOrder任务,也会严格按顺序逐个执行,不会出现并发跑多个order任务的情况
注意事项
- 不要在通用队列worker的
--queue参数里加入order,否则会重新出现多进程并发抢order任务的问题 - 拆分配置后总worker数保持为8,和原配置的进程规模一致,不会额外消耗服务器资源
- 独立拆分日志文件,方便后续分别排查不同队列的任务运行异常
内容的提问来源于stack exchange,提问作者Mwthreex
相关产品推荐
相关产品推荐

