laravel 的 queue 使用注意事項


 laravel 的 queue 使用注意事項

 

1. 在修改 queue 相關代碼后,必須要使用 php artisan queue:restart 來重啟隊列服務,否則所做的修改可能不會生效(沒法重現了,按理說應該和使用 queue:listen 或 queue:work 有關,不過最好還是重啟;可能和 supervisor 開啟多個 queue:work 進程也有關系,本地測試的時候只有一個進程)。

文檔:

 

2、開發環境下以同步的方式執行隊列,將 queue driver 的值改為 sync,注意,如果 queue 有輸出的話,可能會導致一些問題,如:本來應該只返回 json 串的,然后 queue 里面有輸出,導致前端 json 解析失敗。

 

3、什么時候使用 queue:listen?什么時候使用 queue:work?

官網文檔有一段描述是:

在 queue:work Artisan 命令里包含了 --daemon 選項,強制隊列服務器持續處理任務,而不需要重新啟動整個框架。比起 queue:listen 命令,這將明顯的減少 CPU 的用量。

使用 queue:work 的時候不需要重現啟動整個框架,這可能是 1 中可能修改 Job 后不生效的問題。

 

4、多個項目同時部署時候的沖突

laravel 中隊列任務使用 redis 驅動情況下保存的時候的緩存 key 是不帶前綴的,比如 A 項目 dispatch 了一個 a job,保存在了 queues:default,然后我們去 B 項目 dispatch 另一個 job,我們發現它們保存在了相同的 redis key 中

 

這樣會導致的問題是:在一個項目中跑 php artisan queue:work 會拿到另外一個項目的 job,這樣就會導致一些不必要的異常,因為在反序列化的過程中會找不到對應的類。 

原因:config/queue.php 中配置的默認 queue 都是 default:

解決辦法:

a、自己用的是 5.1 版本,網上有說可以修改 cache prefix 解決,但是 laravel 5.1 行不通,可能新版本可以

b、為 job 指定不同的 queue,如 dispatch job 的時候可以 dispatch((new xxJob())->onQueue('xxQueue')),這樣一來,job 就保存在了 queues:xxQueue 中,但是還是得注意,如果還有其他項目,不要取相同名字。同時,這樣一來,我們的 queue:work 或者 queu:listen 命令也要加上 --queue 參數了,如 php artisan queue:work --queue=testQueue,否則還是會去 queues:default 里面找。如下:

c、直接修改 config/queue.php,修改 redis.queue 為一個唯一的名字。如:

 

這樣一來,我們的 job 就不會和其他項目的混在一起了。

 

個人看法:最好的實踐應該還是,不同的隊列使用不同的名字(即使是同一個項目),這樣會更便於管理。

 

5. 給隊列的 Job 對象設置模型對象屬性的時候,最后處理隊列的時候會重新查詢這個模型的數據。

詳細見:\Illuminate\Queue\SerializesModels

也就是說,我們如果想在新建 Job 實例的時候,通過 setAttribute 設置了一個模型實例的屬性,想在 handle 里面獲取這個屬性的話,是獲取不到的。因為序列化隊列任務的時候只會保存模型實例的幾個關鍵屬性,詳細見:\Illuminate\Contracts\Database\ModelIdentifier

 

擴展:

1、監控 redis:redis-cli > monitor

2、關於 laravel 隊列基本工作方式:dispatch 一個 job 的時候,laravel 把 job 序列化保存到相應的 driver 中(redis、database、file...),然后 queue:listen 或 queue:work 的時候會從對應的 driver 里面取出這個 job,對 payload 反序列化,然后調用 job 里面的 handle 方法進行 job 的處理。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM