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队列中。

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

posted @ 2018-11-29 03:52  萝卜er  阅读(1552)  评论(0编辑  收藏  举报