Laravel隊列的一些細枝末節

jopen 9年前發布 | 12K 次閱讀 Laravel Web框架
 

因為我崇尚簡單,所以我憎恨一切所謂的「重量級」框架,比如「Laravel」,有時候這種憎恨甚至到了偏執的程度,以至于如果我看到簡歷里寫著 諸如「精通 Laravel」之類的話,那么便會毫不猶豫的 PASS 掉候選人。不過現在我承認有點喜歡「Laravel」了,雖然性能依然是無法回避的短板,但是又有幾個網站能觸及其性能瓶頸呢?而它豐富的組件則實實在在 的節約了開發者大把的時間,比如本文要說的隊列。

在 Laravel 里調用隊列功能是非常簡單的一件事情,詳細介紹參考 官方文檔

<?php \Queue::pushOn('mail', new \App\Commands\Mail($data)); ?>

隊列包含了多種驅動:比如 sync、database、redis、beanstalk 等等。其中 sync 乍一看會覺得很奇怪,不過實際上它在開發測試階段超級方便,此外 database、redis 等方案更像是一種模擬,所以說 beanstalk 是目前最合適的選擇。當然, beanstalknsq 之類的隊列相比,功能上明顯差一個檔次,但是,beanstalk 貴在簡單易用。

Laravel 隊列的消費者有兩種啟動方式,分別是:queue:listen 和 queue:work,我建議你徹底忘記第一種方式,我甚至不理解它為什么存在,因為它不僅低效,而且可能會導致一些莫名其妙的問題,具體可以參考: 一個Laravel隊列引發的報警

一旦選擇了 queue:work 方式,需要注意有幾個缺省值如果設置不當會出問題:

  • Delay :如果一個任務失敗了,那么它會延遲幾秒后再重新執行。此時間的缺省值為「0」,也就是說不延遲。通常這不是一個好選擇,比如遭遇網絡不穩定,此時一旦失敗,如果不延遲立刻重試,多半還是會失敗。建議設置為「1」。
  • Sleep :如果沒有有效的任務,那么系統暫停幾秒后再重新檢查。此時間的缺省值為「3」。不過如此一來的話,那么如果突然來了一個新任務,那么就可能暫停3秒后才能開始響應,很多時候這顯得有點太長了。建議設置為「1」。
  • Tries :如果一個任務失敗了,那么重試幾次。此次數的缺省值為「0」,不過它的含義可不是不重試,而是不斷重試。某些時候,如果問題比較嚴重,不斷重試就等同于死循環。建議設置為「3」。

在生產環境中,很容易忽視的一點是監控隊列是否發生了擁堵,以 beanstalk 為例,它提供了 stats 命令,讓我們能夠很方便的查詢隊列狀態:

shell> echo -e "stats\r" | nc <IP> <PORT>

不過這個命令有很多輸出,我們如何判斷哪些和擁堵相關呢?最簡單的方法是人為的制造一些擁堵的故障,然后對比前后的結果找差異,我試驗的結果是如下幾項:

  • current-jobs-urgent
  • current-jobs-ready
  • current-jobs-reserved
  • current-jobs-delayed
  • current-jobs-buried

我們可以通過 zabbix 很方便的監控 beanstalk 是否發生了擁堵:

Laravel隊列的一些細枝末節

Beanstalk Jobs

具體的配置方法我就不贅述了,大家可以參考官網中對于 UserParameters 的描述。

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!