天天看點

Laravel 隊列(queue)的正确使用方法 - 學習/實踐

1.應用場景

主要用于laravel中配合使用隊列進行項目開發.

2.學習/操作

背景:

最近在用laravel5.5穩定版做一個wifi探針的項目, 其中使用到swoole和laravel隊列事件等特性,

其中對隊列的使用使用的方法記錄一下, 友善以後查閱.

Laravel 隊列(queue)的正确使用方法 - 學習/實踐

工具/原料

  • laravel5.5 & composer & lnmp環境
  • php7.1.x+

方法/步驟

  1. 1

    首先檢查自己的環境是否符合要求[其中我用php7是因為我系統裡面有多個php版本]

          php -v

          composer --version

    Laravel 隊列(queue)的正确使用方法 - 學習/實踐
  2. 2

    接着使用composer初始化一個基于laravel5.5版本的項目

          composer create-project laravel/laravel laravel-queue --prefer-dist "5.5.*"

    Laravel 隊列(queue)的正确使用方法 - 學習/實踐
  3. 3

    為了示範隊列的使用,我們将使用基于資料庫驅動的隊列,但是真實項目建議使用redis或者rabbitmq或者fakfa等專業的隊列服務.修改項目中的.env配置檔案

            DB_HOST=資料庫主

            DB_PORT=資料庫端

            DB_DATABASE=資料庫

            DB_USERNAME=資料庫用

            DB_PASSWORD=資料庫密碼

            QUEUE_DRIVER=database

           并建立laravel-queue資料庫 

           CREATE DATABASE `laravel-queue` ;

    Laravel 隊列(queue)的正确使用方法 - 學習/實踐
  4. 4

    準備工作做好了,那我們就開始寫代碼了,我們使用laravel提供的腳手架生成處理隊列的任務類DemoQueue

          php artisan make:job  DemoQueue

    這個時候會在你的項目下面多了一個Jobs目錄,最終生成的任務處理檔案就在目錄下面

        如:  /xxx/laravel-queue/app/Jobs/DemoQueue.php

    Laravel 隊列(queue)的正确使用方法 - 學習/實踐
    Laravel 隊列(queue)的正确使用方法 - 學習/實踐
  5. 處理隊列的任務類,但是現在我們還沒有要處理的隊列,那麼我們接着使用laravel提供的腳手架生成隊列使用的資料庫

           //檢視laravel提供了那些腳手架功能

           php artisan 

           //使用php artisan queue:table 生成資料隊列驅動的表結構

          php artisan queue:table

          //執行資料庫遷移也就是建立表

          php artisan migrate

    執行完上面的動作之後,如果你前面的資料配置正确,那麼你應該和我一樣會看到圖檔上的效果

    Laravel 隊列(queue)的正确使用方法 - 學習/實踐
    Laravel 隊列(queue)的正确使用方法 - 學習/實踐
    Laravel 隊列(queue)的正确使用方法 - 學習/實踐
  6. 資料表也有,那麼模拟幾條隊列資料到隊列裡面去,那麼就随便建立一個控制來模拟幾條資料到隊列服務裡面去.

          //生成控制器

          php artisan make:controller DemoController

         //啟動一個内部虛拟伺服器

         php artisan serve

         //配置web.php的請求路由

         Route::get('demo','[email protected]');

        //新開一個視窗用curl請求

        curl -i localhost:8000/demo

    如果不出意外的話,這個時候jobs表裡面就有了三條待處理的消息了

    Laravel 隊列(queue)的正确使用方法 - 學習/實踐
    Laravel 隊列(queue)的正确使用方法 - 學習/實踐
    Laravel 隊列(queue)的正确使用方法 - 學習/實踐
    Laravel 隊列(queue)的正确使用方法 - 學習/實踐
  7. 消費隊列,前面都好了解就是在消費隊列的時候,有幾個小坑大家要注意,因為在消費隊列的時候誰都不能保證服務就一直在如期執行,總會發生點什麼意外.有人說可以用try catch捕獲,但是不是這樣的,即使你在DemoQueue裡面捕獲,你也拿回去不到異常資訊, 跟蹤源碼發現,是在隊列的接口在進行了捕獲, 那我們先不考慮錯誤的情況, 就假如一切都很順利的執行了

         //執行這個指令消費隊列

         php artisan queue:work --queue=demo

    Laravel 隊列(queue)的正确使用方法 - 學習/實踐
    Laravel 隊列(queue)的正确使用方法 - 學習/實踐
  8. 但是你擔心的事情總會發生的,既然我們知道有些事情會發生那我們就應該提前做好對應的措施,這樣你就有更多的時間學習新的東西,剛才我們在DemoQueue裡面定義了一個$tries 屬性, 隊列在處理次數達到這個值的時候還是沒有成功的話就會寫入到失敗的隊清單裡面去,那現在我們就去模拟一下隊列失敗的情況.

         //在生成3條測試隊列的資料

         curl -i localhost:8000/demo

         //消費隊列

         php artisan queue:work --queue=demo

    這個時候我們看效果, 隊列在嘗試了三次之後失敗了,就把原來的隊列給删除了,這個時候如果我們不及時處理的話,就會丢失資料.通過分析錯誤日志我可以查到一個很重要的資訊,那就是我們缺少一個failed_jobs表

    Laravel 隊列(queue)的正确使用方法 - 學習/實踐
    Laravel 隊列(queue)的正确使用方法 - 學習/實踐
    Laravel 隊列(queue)的正确使用方法 - 學習/實踐
  9. 那問題來了, 我們怎麼儲存處理失敗的隊列那, 其實很簡單laravel的隊列服務提供了補救措施.

            //生成failed_jobs表

            php artisan queue:failed-table

            //執行資料庫遷移

            php artisan migrate

    Laravel 隊列(queue)的正确使用方法 - 學習/實踐
    Laravel 隊列(queue)的正确使用方法 - 學習/實踐
  10. 這下放心了, 有了儲存隊列失敗的表,我們就不要擔心隊列丢失的問題了,再次生成模拟資料,進行隊列消費

         //在生成3條測試隊列的資料

         curl -i localhost:8000/demo

         //消費隊列

         php artisan queue:work --queue=demo

    這次隊列消費還是失敗了,但是奇妙的是我們的失敗隊列被儲存到了failed-table表裡面去了

    Laravel 隊列(queue)的正确使用方法 - 學習/實踐
    Laravel 隊列(queue)的正确使用方法 - 學習/實踐
  11. 即然我知道我們的隊列有問題, 那我們就應該去修複這個bug, 或許這個時候你想問有沒有一種方法,就是隊列處理失敗的時候給開發人員發送郵件通知開發人員緊急修複那?對你想的很對,laravel之是以很優雅就是很多設計都很人性化. laravel提供了一個failed方法,laravel的隊列會在達到最大重試次數還沒有處理成功後就會調用這個方法, 是以你可以可以在這個方法裡面寫發送郵件的邏輯給開發人員發送告警郵件.這個方法接收一個Exception 類型的參數.那我們去增加這個方法.

         //在生成3條測試隊列的資料

         curl -i localhost:8000/demo

         //消費隊列

         php artisan queue:work --queue=demo

    從錯誤日志裡面,我們可以看到failed方法被成功調用了, 所有你可以在這裡寫發送郵件的邏輯了.

    Laravel 隊列(queue)的正确使用方法 - 學習/實踐
    Laravel 隊列(queue)的正确使用方法 - 學習/實踐
    Laravel 隊列(queue)的正确使用方法 - 學習/實踐
  12. 對了, 其實在上一步的時候, 我們還是沒有把剛才失敗的隊列給找回來, 好的馬上就要寫完了, 我們把剛才失敗的隊列找回來, 接着我把我剛才模拟的錯誤代碼去掉, 然後執行laravel提供的方法找回隊列, 找回來的隊列會重重新放到jobs表中.是不是我說的這樣我們可以試試.

           //執行如下指令找回處理失敗的隊列

           php artisan help  queue:retry 

    後面可以跟failed-table表的id,如果跟id的話, 隻會回複對應id值的失敗隊列到jobs表中, 如果跟all的話全部失敗的隊列都會重新放回jobs表中

    Laravel 隊列(queue)的正确使用方法 - 學習/實踐
    Laravel 隊列(queue)的正确使用方法 - 學習/實踐
    Laravel 隊列(queue)的正确使用方法 - 學習/實踐
    Laravel 隊列(queue)的正确使用方法 - 學習/實踐
  13. 最後我們再次執行隊列消費的指令就可以消費剛才失敗的隊列了.

         //消費隊列

         php artisan queue:work --queue=demo

    到這裡,我們要說的隊列的正确使用的方法就到這裡了, 其中有幾個很重要的地方我們要總結一下

          1.執行隊列的時候一定要加上--tries參數 最好也指定消費的隊列名稱和連接配接驅動,如果你不喜歡這樣做的話可以寫到DemoQueue裡面

          如:/xxx/php /yyyy/artisan queue:work redis --sleep=3 --tries=3 --queue=zzz

          2.除了這種方式laravel還提供一種Queue事件監聽的方式來處理失敗的隊列,這種方式大家可以自行嘗試.

  14. 我們學到了什麼?

         一 .或許你看完這篇經驗,還是一頭霧水,那我建議你多看看laravel的手冊,總有一頭你會恍然大悟,會感慨laravel的設計如此的美妙.

         二. 要學會總了解laravel隊列的設計思路, 如果我們的業務也有類似的場景,我們完全可以套用這種設計理念, 這也是我這篇經驗想表達的核心思想, 因為隻有了解了别人造的輪子的優點, 你才可能造出來更好用輪子

         三. 大神們請不拍磚,如果這篇經驗有幫助到你歡迎關注,歡迎點贊.

    END

注意事項

  • 最終的代碼包下載下傳位址 : https://pan.baidu.com/s/1sNUxA8Wd8PliLI5t77hd9A

3.問題/補充

TBD

4.參考

https://jingyan.baidu.com/article/adc81513ae3333f722bf7358.html

後續補充

...