使用 laravel 的 queue 必須知道的一些事

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

文檔:前端

 

二、開發環境下以同步的方式執行隊列,將 queue driver 的值改成 sync,注意,若是 queue 有輸出的話,可能會致使一些問題,如:原本應該只返回 json 串的,而後 queue 裏面有輸出,致使前端 json 解析失敗。laravel

 

三、何時使用 queue:listen?何時使用 queue:work?redis

官網文檔有一段描述是:json

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

使用 queue:work 的時候不須要重現啓動整個框架,這多是 1 中可能修改 Job 後不生效的問題。服務器

 

四、多個項目同時部署時候的衝突框架

laravel 中隊列任務使用 redis 驅動狀況下保存的時候的緩存 key 是不帶前綴的,好比 A 項目 dispatch 了一個 a job,保存在了 queues:default,而後咱們去 B 項目 dispatch 另外一個 job,咱們發現它們保存在了相同的 redis key 中測試

 

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

緣由: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

 

擴展:

一、監控 redis:redis-cli > monitor

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

相關文章
相關標籤/搜索