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  ·  4年前

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

《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
最佳答案

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

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

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

4年前 评论
yangonce (楼主) 4年前
L学习不停 (作者) 4年前
讨论数量: 29

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

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

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

4年前 评论
yangonce (楼主) 4年前
L学习不停 (作者) 4年前

numprocs=1

4年前 评论
yangonce (楼主) 4年前
panda-sir

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

4年前 评论
yangonce (楼主) 4年前

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

4年前 评论
yangonce (楼主) 4年前
L学习不停 4年前
JerryBool (作者) 4年前

建议使用 laravel5.5 + horizon + redis

4年前 评论
yangonce (楼主) 4年前
siyecao

redis没问题的

4年前 评论
yangonce (楼主) 4年前

问题预估:

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

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

4年前 评论
yangonce (楼主) 4年前
Hachiko (作者) 4年前
yangonce (楼主) 4年前
Hachiko (作者) 4年前
yangonce (楼主) 4年前
Hachiko (作者) 4年前
yangonce (楼主) 4年前
Hachiko (作者) 4年前
yangonce (楼主) 4年前
Hachiko (作者) 4年前
游离不2

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

4年前 评论

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

4年前 评论

这是资源抢占问题,多个进程抢到了同一个任务,用redis做驱动,list数据类型只会被第一个进程取出,但redis也不是完善的消息队列,会有丢数据的情况

2年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!