1. 程式人生 > >laravel 訊息佇列淺析

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,就會再次執行。