laravel 消息队列浅析

Posted 萝卜er

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了laravel 消息队列浅析相关的知识,希望对你有一定的参考价值。

  laravel支持消息队列,发短信,发送消息通知 用起来很方便,延时队列还可以用来方式晚上发短信骚扰用户。但是使用的时候遇到了不少问题,比如laravel队列的重试功能,真的是让人很慌,打款或者消息推送,哪个重复了都会造成很大的影响。接下来就列举几个我遇到过的问题,总结一下,防止再次踩坑。

     第一点: 使用worker监听,出队的代码如果又修改,那么上线必须重启监听

     第二点:防止异常重试,异常重试次数可以通过--tries参数来设置,如果一个业务场景是,少发几条没关系,但是一定不能多发,那么可以不重试,attemps参数可以看到重试了几次,delete()方法,可以手动防止重试,将消息删除。

    第三点:防止超时重试, 这个和异常重试不太一样,默认超时时间为60秒,可以通过timeout参数来设置。 如果时间超过60秒,那么这个任务还会被执行。

 

  从原理分析,一个队列开启监听,这个时候会去检查,delayed队列(这个里面装的都是之前执行异常之后放进去的消息,这些消息的延时时间可以通过sleep参数设置,默认3秒),因为delayed队列用的有序集合,可以很方便获取过期的消息,全部放进默认队列(数据结构为列表)中,并将delayed中的删除, 这个时候去检查reserved队列,这个队列也是有序集合,查看过期的(过期时间60秒,可以通过timeout来设置), 将这部分过期的数据重新放进defeat队列,并将reserved中的删除。

  这个时候准备工作就做好了,准备开始执行, 在执行之前,先将defeat队列中的消息放一份到reserved中(设置有效时间为timeout参数),这个时候从defeat队列弹出数据开始执行,如果执行成功,那么删除reserved队列中的数据。如果执行报错 那么也把消息从reserved队列中删除,并将这条消息放进delayed队列中。

如果一直执行,那么reserved中的数据就一直在,直到过期。 当下一次别的请求进来的时候,又回重复上述动作,这个时候reserved中的消息就会被再放进defeat,就会再次执行。

以上是关于laravel 消息队列浅析的主要内容,如果未能解决你的问题,请参考以下文章

蚂蚁金服:消息队列事务型消息原理浅析

redis 属于redis的 “消息队列”:redis stream(浅析)

redis 属于redis的 “消息队列”:redis stream(浅析)

消息队列服务(MQS)技术浅析

浅析消息队列之rabbitMQ

云原生消息队列 Pulsar 浅析