supervisor 开启多个进程,导致队列重复执行

我有个队列用来发送短信通知,之前我配置supervistor的时候只开启了一个进程,所以并没有发现问题。数据多了,我就想多开几个进程,可是当我多开几个进程的时候,一个队列就会重复执行,并且重复执行的次数就是设置的进程数量,比如我numprocs=4,最后就会发送4条短信到同一个手机号上。我队列驱动是database;

[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php 项目路径/artisan queue:work queue=sms --sleep=3 --tries=3
autostart=true
autorestart=true
user=forge
numprocs=4
redirect_stderr=true
stdout_logfile=/home/forge/app.com/worker.log
stopwaitsecs=3600
附言 1  ·  3个月前

感谢各位的帮助,目前问题已解决。队列驱动换成了redis。

《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
最佳答案

如果你用database又开启多个消费者的话,你需要做这几个步骤:
1.消费者判断当前数据是否被消费,如果消费过了就不做任何动作
2.消费者消费数据的时候,用悲观锁锁住当前数据,消费完成后标记已经消费

数据库用来做队列不是明智之选。因为mysql数据库并不擅长做队列,包括redis也是。当程序消费者同时消费的过多,会造成mysql性能下降。mysql连接是有上限的,可执行的线程也是有上限的。何况mysql做延迟队列性能也很差,需要一直进行扫描。

综上,建议你换成rabbitmq,rocketmq或者kafka。我觉得rabbitmq挺好用,推荐你使用。

3个月前 评论
yangonce (楼主) 3个月前
L学习不停 (作者) 3个月前
讨论数量: 9

numprocs=1

3个月前 评论
yangonce (楼主) 3个月前
panda-sir

没用过database做驱动 可能需要代码里去处理这个问题吧 我一般用redislist结构或者专业级的消息队列

3个月前 评论
yangonce (楼主) 3个月前

如果你用database又开启多个消费者的话,你需要做这几个步骤:
1.消费者判断当前数据是否被消费,如果消费过了就不做任何动作
2.消费者消费数据的时候,用悲观锁锁住当前数据,消费完成后标记已经消费

数据库用来做队列不是明智之选。因为mysql数据库并不擅长做队列,包括redis也是。当程序消费者同时消费的过多,会造成mysql性能下降。mysql连接是有上限的,可执行的线程也是有上限的。何况mysql做延迟队列性能也很差,需要一直进行扫描。

综上,建议你换成rabbitmq,rocketmq或者kafka。我觉得rabbitmq挺好用,推荐你使用。

3个月前 评论
yangonce (楼主) 3个月前
L学习不停 (作者) 3个月前

应该不是supervisor的问题。因为每个 job 从数据库中被 pop 出来,laravel都会加锁的,防止重复消费。

3个月前 评论
yangonce (楼主) 3个月前
L学习不停 3个月前
di-gua (作者) 3个月前

建议使用 laravel5.5 + horizon + redis

3个月前 评论
yangonce (楼主) 3个月前
siyecao

redis没问题的

3个月前 评论
yangonce (楼主) 3个月前

问题预估:

  1. 结论:和supervisor无关,对队列的概念理解有误,队列最基本的原则就是保证数据不被重复消费,就算是用 database 也没问题,现上跑了一年没问题,numprocs=8
  2. 解决:加入队列,是把手机号作为 job 参数传入,job里面根据手机号,再做相应逻辑,就没这个问题,因为不会被重复消费。
  3. 分析:把数据写入表,再分发 job 去表里取数据处理,多进程肯定会取到重复数据,伪sql:SELECT * FROM mobile ORDER BY id DESC LMMIT 1 取到重复数据,很正常

PS:不找到问题的本质,换 redisrabbitmqrocketmqkafka 都解决不了你现有问题

3个月前 评论
yangonce (楼主) 3个月前
Hachiko (作者) 3个月前
yangonce (楼主) 3个月前
Hachiko (作者) 3个月前
yangonce (楼主) 3个月前
Hachiko (作者) 3个月前
yangonce (楼主) 3个月前
Hachiko (作者) 3个月前
yangonce (楼主) 3个月前
Hachiko (作者) 3个月前
游离不2

database 存在并发的问题,还是 redis 靠谱点,或者看有没有办法上锁。

3个月前 评论

数据库我的理解是要加锁避免多个进程执行同一个数据

3个月前 评论

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!