[TOC]
# 一些小技巧
1. 在開發環境我們想測試的時候,可以把 Queue driver 設置成為 sync,這樣隊列就變成了同步執行,方便調試隊列里面的任務。
2. Job 里面的 handle 方法是可以注入別的 class 的,就像在 Controller action 里面也可以注入一樣。
問答
# 問:什么時候使用 queue:listen 什么時候使用 queue:work?
答:Laravel 5.3 的文檔已經不寫 queue:listen這個指令怎么用了,所以你可以看出來可能官方已經不怎么建議使用 queue:listen了,但是在本地調試的時候要使用 queue:listen,因為 queue:work在啟動后,代碼修改,queue:work不會再 Load 上下文,但是 queue:listen仍然會重新 Load 新代碼。
其余情況全部使用 queue:work吧,因為效率更高。
# 命令講解
以下是常用的指令,我講解一下
~~~
php artisan queue:work --daemon --quiet --queue=default --delay=3 --sleep=3 --tries=3
~~~
--daemon
> The queue:work Artisan command includes a —daemon option for forcing the queue worker to continue processing jobs without ever re-booting the framework. This results in a significant reduction of CPU usage when compared to the queue:listen command
總體來說,在 supervisor 中一般要加這個 option,可以節省 CPU 使用。
--quiet
> 不輸出任何內容
--delay=3
> 一個任務失敗后,延遲多長時間后再重試,單位是秒。這個值的設定我個人建議不要太短,因為一個任務失敗(比如網絡原因),重試時間太短可能會出現連續失敗的情況。
--sleep=3
> 去 Redis 中拿任務的時候,發現沒有任務,休息多長時間,單位是秒。這個值的設定要看你的任務是否緊急,如果是那種非常緊急的任務,不能等待太長時間。
--tries=3
> 定義失敗任務最多重試次數。這個值的設定根據任務的重要程度來確定,一般 3 次比較適合。
# Redis 中發生了什么事情
~~~
dispatch(new ExampleJob());
~~~
如果一個任務進入 default 隊列,會發生:
~~~
127.0.0.1:6379>monitor
"RPUSH"
"queues:default"
"{\"job\":\"Illuminate\\\\Queue\\\\CallQueuedHandler@call\",\"data\":{\"commandName\":\"App\\\\Jobs\\\\ExampleJob\",\"command\":\"O:19:\\\"App\\\\Jobs\\\\ExampleJob\\\":7:{s:17:\\\"\\u0000*\\u0000userIdentifier\\\";N;s:9:\\\"\\u0000*\\u0000realIp\\\";N;s:12:\\\"\\u0000*\\u0000requestId\\\";N;s:6:\\\"\\u0000*\\u0000job\\\";N;s:10:\\\"connection\\\";N;s:5:\\\"queue\\\";N;s:5:\\\"delay\\\";N;}\"},\"id\":\"bwA7ICPqnjYiM0ErjRBNwn0kVWF6KeAs\",\"attempts\":1}"
~~~
redis 中會出現如下內容:
~~~
127.0.0.1:6379> keys queue*
1) "queues:default"
~~~
如果執行命令:
~~~
php artisan queue:work --daemon --quiet --queue=default --delay=3 --sleep=3 --tries=3
~~~
# Redis 會發生什么事情?
第一步:查看是否需要重啟,如果 laravel:illuminate:queue:restart 存在,就重啟隊列(代碼更新后,一定要重啟隊列,否則隊列不會讀取最新代碼)。
~~~
"GET"
"laravel:illuminate:queue:restart"
~~~
第二步:查看zset queues:default:delayed ,注意這里的事務
~~~
"WATCH"
"queues:default:delayed"
"ZRANGEBYSCORE"
"queues:default:delayed"
"-inf"
"1485386782"
"UNWATCH"
~~~
第三步:查看 zset queues:default:reserved,注意這里的事務
~~~
"WATCH"
"queues:default:reserved"
"ZRANGEBYSCORE"
"queues:default:reserved"
"-inf"
"1485386782"
"UNWATCH"
~~~
第四步:從 queue:default list 中取任務,如果有任務,要把任務先暫存到 queues:default:reserved 中(過期時間60秒,Redis Queue 里面寫一個任務最多執行60秒)。
任務執行結束會把 queues:default:reserved 中的任務刪除,如果任務報錯(Throw exception),也會把queues:default:reserved 中的任務刪除,然后把任務扔進 queues:default:delay,delay 的秒數是 3 秒(因為我們上面參數配置的是 --delay=3)。
~~~
"LPOP"
"queues:default"
#取出任務后,先要放到 queues:default:reserved zset 中
"ZADD"
"queues:default:reserved"
"1485386842"
"{\"job\":\"Illuminate\\\\Queue\\\\CallQueuedHandler@call\",\"data\":{\"commandName\":\"App\\\\Jobs\\\\ExampleJob\",\"command\":\"O:19:\\\"App\\\\Jobs\\\\ExampleJob\\\":7:{s:17:\\\"\\u0000*\\u0000userIdentifier\\\";N;s:9:\\\"\\u0000*\\u0000realIp\\\";N;s:12:\\\"\\u0000*\\u0000requestId\\\";N;s:6:\\\"\\u0000*\\u0000job\\\";N;s:10:\\\"connection\\\";N;s:5:\\\"queue\\\";N;s:5:\\\"delay\\\";N;}\"},\"id\":\"bwA7ICPqnjYiM0ErjRBNwn0kVWF6KeAs\",\"attempts\":1}"
# 任務執行完畢后, 從 queues:default:reserved zset 中刪除
"ZREM"
"queues:default:reserved"
"{\"job\":\"Illuminate\\\\Queue\\\\CallQueuedHandler@call\",\"data\":{\"commandName\":\"App\\\\Jobs\\\\ExampleJob\",\"command\":\"O:19:\\\"App\\\\Jobs\\\\ExampleJob\\\":7:{s:17:\\\"\\u0000*\\u0000userIdentifier\\\";N;s:9:\\\"\\u0000*\\u0000realIp\\\";N;s:12:\\\"\\u0000*\\u0000requestId\\\";N;s:6:\\\"\\u0000*\\u0000job\\\";N;s:10:\\\"connection\\\";N;s:5:\\\"queue\\\";N;s:5:\\\"delay\\\";N;}\"},\"id\":\"bwA7ICPqnjYiM0ErjRBNwn0kVWF6KeAs\",\"attempts\":1}"
# 如果任務失敗,會放到 queue:default:delay zset 中
"ZADD"
"queues:default:delayed"
"1485386783"
"{\"job\":\"Illuminate\\\\Queue\\\\CallQueuedHandler@call\",\"data\":{\"commandName\":\"App\\\\Jobs\\\\ExampleJob\",\"command\":\"O:19:\\\"App\\\\Jobs\\\\ExampleJob\\\":7:{s:17:\\\"\\u0000*\\u0000userIdentifier\\\";N;s:9:\\\"\\u0000*\\u0000realIp\\\";N;s:12:\\\"\\u0000*\\u0000requestId\\\";N;s:6:\\\"\\u0000*\\u0000job\\\";N;s:10:\\\"connection\\\";N;s:5:\\\"queue\\\";N;s:5:\\\"delay\\\";N;}\"},\"id\":\"uuPBCq4QE9ocnw8UbkLhUl2Lh07yPm6M\",\"attempts\":1}"
~~~
# Redis 中的數據結構和操作:
1. queue:default
數據結構: List,
操作: LRANGE "queues:default" 0 -1 獲取 List 里面的所有數據。
2. queue:default:reserved 和 queue:default:delay
數據結構: Zset,時間是 zset 的 score,通過 score 來排序。
操作: ZRANGE ”queues:default:reserved“ 0 -1 獲取 zset 里面的所有數據。 ZRANGEBYSCORE queues:default:reserved -inf +inf 通過時間來排序獲取所有數據。
# 注意
Redis 里面一個任務默認最多執行60秒,如果一個任務60秒沒有執行完畢,會繼續放回到隊列中,循環執行,那酸爽
- 配置
- composer安裝
- composer用法
- composer版本約束表達
- phpstorm
- sftp文件同步
- php類型約束
- laradock
- 配置文件緩存詳解
- git
- 自定義函數
- 核心概念
- IOC
- 服務提供者
- Facade
- 契約
- 生命周期
- 路由
- 請求
- 命名路由
- 路由分組
- 資源路由
- 控制器路由
- 響應宏
- 響應
- Command
- 創建命令
- 定時任務
- console路由
- 執行用戶自定義的定時任務
- artisan命令
- 中間件
- 創建中間件
- 使用中間件
- 前置和后置
- 詳細介紹
- 訪問次數限制
- 為 VerifyCsrfToken 添加過濾條件
- 單點登錄
- 事件
- 創建
- ORM
- 簡介
- DB類
- 配置
- CURD
- queryScope和setAttribute
- 查看sql執行過程
- 關聯關系
- 一對一
- 一對多
- 多對多
- 遠程關聯
- 多態一對多
- 多態多對多
- 關聯數據庫的調用
- withDefault
- 跨模型更新時間戳
- withCount,withSum ,withAvg, withMax,withMin
- SQL常見操作
- 模型事件
- 模型事件詳解
- 模型事件與 Observer
- deleted 事件未被觸發
- model validation
- ORM/代碼片段
- Repository模式
- 多重where語句
- 中間表類型轉換
- Collection集合
- 新增的一些方法
- 常見用法
- 求和例子
- 機場登機例子
- 計算github活躍度
- 轉化評論格式
- 計算營業額
- 創建lookup數組
- 重新組織出表和字段關系并且字段排序
- 重構循環
- 其他例子
- 其他問題一
- 去重
- 第二個數組按第一個數組的鍵值排序
- 搜索ES
- 安裝
- 表單
- Request
- sessiom
- Response
- Input
- 表單驗證
- 簡介
- Validator
- Request類
- 接口中的表單驗證
- Lumen 中自定義表單驗證返回消息
- redis
- 廣播事件
- 發布訂閱
- 隊列
- 守護進程
- redis隊列的坑
- beanstalkd
- rabbitmq
- redis隊列
- 日志模塊
- 錯誤
- 日志詳解
- 數據填充與遷移
- 生成數據
- 數據填充seed
- migrate
- 常見錯誤
- Blade模板
- 流程控制
- 子視圖
- URL
- 代碼片段
- Carbon時間類
- 一些用法
- 郵件
- 分頁
- 加密解密
- 緩存
- 文件上傳
- 優化
- 隨記
- 嵌套評論
- 判斷字符串是否是合法的 json 字符串
- 單元測試
- 計算出兩個日期的diff
- 自定義一個類文件讓composer加載
- 時間加減
- 對象數組互轉方法
- 用戶停留過久自動退出登錄
- optional 輔助方法
- 文件下載
- Api
- Dingo api
- auth.basic
- api_token
- Jwt-Auth
- passport
- Auth
- Authentication 和 Authorization
- Auth Facade
- 授權策略
- Gates
- composer包
- debug包
- idehelp包
- image處理
- 驗證碼
- jq插件
- 第三方登錄
- 第三方支付
- log顯示包
- 微信包
- xss過濾
- Excel包
- MongoDB
- php操作
- 聚合查詢
- 發送帶附件郵件
- 中文轉拼音包
- clockwork網頁調試
- emoji表情
- symfony組件
- swooletw/laravel-swoole
- 常見問題
- 跨域問題
- Laravel隊列優先級的一個坑
- cache:clear清除緩存問題
- .env無法讀取
- 源碼相關基礎知識
- __set和__get
- 依賴注入、控制反轉和依賴倒置原則
- 控制反轉容器(Ioc Container)
- 深入服務容器
- call_user_func
- compact
- 中間件簡易實現
- array_reduce
- 中間件實現代碼
- Pipeline管道操作
- composer自動加載
- redis延時隊列
- 了解laravel redis隊列
- cli
- 源碼解讀
- Facade分析
- Facade源碼分析
- IOC服務容器
- 中間件原理
- 依賴注入淺析
- 微信
- 微信公眾號
- 常用接收消息
- 6大接收接口
- 常用被動回復消息
- 接口調用憑證
- 自定義菜單
- 新增素材
- 客服消息
- 二維碼
- 微信語音
- LBS定位
- 網頁授權
- JSSDK
- easywechat
- 小程序
- 小程序配置app.json