Laravel框架隊(duì)列原理與用法分析
本文實(shí)例講述了Laravel框架隊(duì)列原理與用法。分享給大家供大家參考,具體如下:
最近有朋友有朋友問laravel隊(duì)列的實(shí)現(xiàn)原理和經(jīng)驗(yàn),剛好用過所以整理了一下分享給大家。
laravel隊(duì)列配置參見:http://d.laravel-china.org/docs/5.1/queues
原理分析
創(chuàng)建分發(fā)任務(wù)方法
class TestController extends Controller { //其他方法 //發(fā)送消息 public function SendMessage(Request $request){ ... $this->dispatch((new SendMessage($sendParams))->onQueue('snail:SendMessage')); } }
內(nèi)部實(shí)現(xiàn):
創(chuàng)建消費(fèi)任務(wù)
命令行運(yùn)行如下命令:
/home/niuyufu/php/bin/php /home/niuyufu/webroot/assistant_api/artisan queue:work --queue=snail:SendMessage --tries=3 --memory=512 --daemon
內(nèi)部實(shí)現(xiàn):
隊(duì)列消息分析:
監(jiān)控redis對應(yīng)隊(duì)列消息,具體產(chǎn)生的消息操作,如下:
tail -f | redis-cli -h 10.94.120.13 -p 6380 monitor | grep "queues:snail"
1492446053.406282 [0 10.95.117.155:57132] "WATCH" "queues:snail:SendMessage:delayed"
1492446053.406452 [0 10.95.117.155:57132] "ZRANGEBYSCORE" "queues:snail:SendMessage:delayed" "-inf" "1492446053"
1492446053.406754 [0 10.95.117.155:57132] "WATCH" "queues:snail:SendMessage:reserved"
1492446053.406842 [0 10.95.117.155:57132] "ZRANGEBYSCORE" "queues:snail:SendMessage:reserved" "-inf" "1492446053"
1492446053.407029 [0 10.95.117.155:57132] "LPOP" "queues:snail:SendMessage"
1492446053.407700 [0 10.95.117.155:57132] "ZADD" "queues:snail:SendMessage:reserved" "1492446113" "{job}"
1492446053.463953 [0 10.95.117.155:57132] "ZREM" "queues:snail:SendMessage:reserved" "{job}"
PS:如果你的redis是codis的話,注意了,因?yàn)閏odis禁用方法列表
KEYS, MOVE, OBJECT, RENAME, RENAMENX, SORT, SCAN, BITOP,MSETNX, BLPOP, BRPOP, BRPOPLPUSH, PSUBSCRIBE,PUBLISH, PUNSUBSCRIBE, SUBSCRIBE, UNSUBSCRIBE, DISCARD, EXEC, MULTI, UNWATCH, WATCH, SCRIPT EXISTS, SCRIPT FLUSH, SCRIPT KILL, SCRIPT LOAD, AUTH, ECHO, SELECT, BGREWRITEAOF, BGSAVE, CLIENT KILL, CLIENT LIST, CONFIG GET, CONFIG SET, CONFIG RESETSTAT, DBSIZE, DEBUG OBJECT, DEBUG SEGFAULT, FLUSHALL, FLUSHDB, INFO, LASTSAVE, MONITOR, SAVE, SHUTDOWN, SLAVEOF, SLOWLOG, SYNC, TIME
所以執(zhí)行消費(fèi)任務(wù)會有以下錯誤:
[Predis\Connection\ConnectionException]
Error while reading line from the server. [tcp://100.90.154.39:3000]
解決方法為修改config/queue.php
'redis' => [ 'driver' => 'redis', 'connection' => 'default', 'queue' => 'default', 'expire' => null, //禁用即可 ],
優(yōu)化日志處理:
如果你的系統(tǒng)有切割文件日志操作。會發(fā)現(xiàn)雖然日志被切分了,但程序卻沒有往新文件里寫入。如,2017-04-18 13:50啟動的項(xiàng)目,日志會一直打到 snail.log.2017041813上。
改進(jìn)方案:
app/Jobs/Job.php文件中添加如下方法:
public function releaseLoggerFile(){ $handles=\Log::getMonolog()->getHandlers(); if(!is_array($handles) || empty($handles)){ return; } foreach($handles as $handle){ if(method_exists($handle, "close")){ $handle->close(); } } return; }
在具體job實(shí)現(xiàn)類中的handle方法結(jié)尾添加:
public function handle() { ... $this->releaseLoggerFile(); //釋放log文件 }
線上部署
創(chuàng)建任務(wù)shell
#!/bin/sh day=$(date +'%y%m%d') now=$(date +"%F %T") php_command="/home/niuyufu/php/bin/php" command="/home/niuyufu/webroot/snail_api/artisan" log="/home/niuyufu/webroot/log/wave" queue_name_arr=("snail:SendMessage" "snail:SendMessageToApp") case $1 in "run") for queue_name in ${queue_name_arr[*]} do count=$(ps aux | grep artisan |grep queue=${queue_name} | grep -v grep | wc -l) if [ ${count} -lt 1 ];then echo "${now}:${queue_name} process has exit ${count}\n"; nohup $php_command $command queue:work --queue=${queue_name} --tries=3 --memory=512 --daemon >> $log/queueMonitor.log 2>&1 & else echo "${now}:${queue_name} process is runing"; fi done ;; "stop") kill -9 $(ps -ef | grep "queue:work" | grep -v grep | awk '{print $2}' | tr -s '\n' ' ') echo ${now}."Queue process all stop"; ;; "list") ps -ef | grep "queue:work" | grep -v grep ;; *) echo " Usage: QueueMonitorCommandShell.sh [run|stop|list] " ;; esac
總結(jié):
laravel這邊的延遲隊(duì)列使用了三個隊(duì)列。
queue:default:delayed // 存儲延遲任務(wù)
queue:default // 存儲"生"任務(wù),就是未處理任務(wù)
queue:default:reserved // 存儲待處理任務(wù)
任務(wù)在三個隊(duì)列中進(jìn)行輪轉(zhuǎn),最后一定進(jìn)入到queue:default:reserved,并且成功后把任務(wù)從這個隊(duì)列中刪除。
laravel5.1 使用了watch來控制隊(duì)列的原子操作,但由于codis本身不支持 watch 方法。所以使用codis不能完全體驗(yàn)隊(duì)列功能:延遲隊(duì)列不支持、不支持?jǐn)?shù)據(jù)重跑,對線上數(shù)據(jù)比較嚴(yán)格操作謹(jǐn)慎使用。
laravel5.3 之后redis隊(duì)列 開始使用lua腳本支持的隊(duì)列原子操作,它沒有使用 watch multi等操作,所以如果線上codis 支持lua的話,可以完整體驗(yàn)到隊(duì)列功能。
參考文檔:
https://laravel-china.org/articles/4169/analysis-of-laravel-message-queue
http://laravelacademy.org/post/2012.html
更多關(guān)于Laravel相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Laravel框架入門與進(jìn)階教程》、《php優(yōu)秀開發(fā)框架總結(jié)》、《php面向?qū)ο蟪绦蛟O(shè)計入門教程》、《php+mysql數(shù)據(jù)庫操作入門教程》及《php常見數(shù)據(jù)庫操作技巧匯總》
希望本文所述對大家基于Laravel框架的PHP程序設(shè)計有所幫助。
- laravel5.6 框架郵件隊(duì)列database驅(qū)動簡單demo示例
- Laravel使用Queue隊(duì)列的技巧匯總
- Docker部署Laravel應(yīng)用實(shí)現(xiàn)隊(duì)列&任務(wù)調(diào)度
- Laravel 6 將新增為指定隊(duì)列任務(wù)設(shè)置中間件的功能
- Laravel 隊(duì)列使用的實(shí)現(xiàn)
- Laravel中為什么不使用blpop取隊(duì)列詳析
- 關(guān)于 Laravel Redis 多個進(jìn)程同時取隊(duì)列問題詳解
- 源碼分析 Laravel 重復(fù)執(zhí)行同一個隊(duì)列任務(wù)的原因
- Laravel使用消息隊(duì)列需要注意的一些問題
- Laravel中利用隊(duì)列發(fā)送郵件的方法示例
- 淺談Laravel隊(duì)列實(shí)現(xiàn)原理解決問題記錄
- 淺析Laravel5中隊(duì)列的配置及使用
- PHP的Laravel框架中使用消息隊(duì)列queue及異步隊(duì)列的方法
- Laravel 4.2 中隊(duì)列服務(wù)(queue)使用感受
- Laravel框架中隊(duì)列和工作(Queues、Jobs)操作實(shí)例詳解
相關(guān)文章
thinkphp文件引用與分支結(jié)構(gòu)用法實(shí)例
這篇文章主要介紹了thinkphp文件引用與分支結(jié)構(gòu)用法,以實(shí)例形式演示了css與js文件導(dǎo)入的方法,以及if與switch語句的用法,需要的朋友可以參考下2014-11-11Thinkphp框架+Layui實(shí)現(xiàn)圖片/文件上傳功能分析
這篇文章主要介紹了Thinkphp框架+Layui實(shí)現(xiàn)圖片/文件上傳功能,結(jié)合實(shí)例形式詳細(xì)分析了Thinkphp+Layui實(shí)現(xiàn)圖片文件上傳的具體步驟、原理與相關(guān)操作技巧,需要的朋友可以參考下2020-02-02ThinkPHP5.1框架頁面跳轉(zhuǎn)及修改跳轉(zhuǎn)頁面模版示例
這篇文章主要介紹了ThinkPHP5.1框架頁面跳轉(zhuǎn)及修改跳轉(zhuǎn)頁面模版,結(jié)合實(shí)例形式分析了thinkPHP5.1框架進(jìn)行頁面跳轉(zhuǎn)及修改跳轉(zhuǎn)模板相關(guān)操作技巧,需要的朋友可以參考下2019-05-05PHP調(diào)用OpenOffice實(shí)現(xiàn)word轉(zhuǎn)PDF的方法
下面小編就為大家?guī)硪黄狿HP調(diào)用OpenOffice實(shí)現(xiàn)word轉(zhuǎn)PDF的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-11-11JavaScript實(shí)現(xiàn)刪除電腦的關(guān)機(jī)鍵
本文給大家分享的是一個惡作劇小程序,使用JavaScript實(shí)現(xiàn)刪除電腦的關(guān)機(jī)鍵,非常有意思,主要是通過ActiveX操作注冊表來實(shí)現(xiàn),有需要的小伙伴可以參考下2016-07-07php解析url并得到url中的參數(shù)及獲取url參數(shù)的四種方式
本文給大家介紹php解析url并得到url中的參數(shù)及獲取url參數(shù)的四種方式,涉及到將字符串參數(shù)變?yōu)閿?shù)組,將參數(shù)變?yōu)樽址南嚓P(guān)知識,本文代碼簡單易懂,感興趣的朋友一起看看吧2015-10-10