1. 程式人生 > >laravel 消息隊列淺析

laravel 消息隊列淺析

del 設置 att 超過 但是 -- 準備工作 執行 重試

  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 消息隊列淺析