主頁 > 知識庫 > Laravel框架隊列原理與用法分析

Laravel框架隊列原理與用法分析

熱門標簽:團購網站 銀行業(yè)務 阿里云 Mysql連接數(shù)設置 服務器配置 Linux服務器 科大訊飛語音識別系統(tǒng) 電子圍欄

本文實例講述了Laravel框架隊列原理與用法。分享給大家供大家參考,具體如下:

最近有朋友有朋友問laravel隊列的實現(xiàn)原理和經驗,剛好用過所以整理了一下分享給大家。

laravel隊列配置參見:http://d.laravel-china.org/docs/5.1/queues

原理分析

創(chuàng)建分發(fā)任務方法

class TestController extends Controller
{
  //其他方法
  //發(fā)送消息
  public function SendMessage(Request $request){
    ...
    $this->dispatch((new SendMessage($sendParams))->onQueue('snail:SendMessage'));
  }
}

內部實現(xiàn):

創(chuàng)建消費任務

命令行運行如下命令:

/home/niuyufu/php/bin/php /home/niuyufu/webroot/assistant_api/artisan queue:work --queue=snail:SendMessage --tries=3 --memory=512 --daemon

內部實現(xiàn):

隊列消息分析:

監(jiān)控redis對應隊列消息,具體產生的消息操作,如下:

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的話,注意了,因為codis禁用方法列表

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í)行消費任務會有以下錯誤:

[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啟動的項目,日志會一直打到 snail.log.2017041813上。

改進方案:

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實現(xiàn)類中的handle方法結尾添加:

public function handle()
{
  ...
  $this->releaseLoggerFile(); //釋放log文件
}

線上部署

創(chuàng)建任務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

總結:

laravel這邊的延遲隊列使用了三個隊列。

queue:default:delayed // 存儲延遲任務
queue:default // 存儲"生"任務,就是未處理任務
queue:default:reserved // 存儲待處理任務
任務在三個隊列中進行輪轉,最后一定進入到queue:default:reserved,并且成功后把任務從這個隊列中刪除。

laravel5.1 使用了watch來控制隊列的原子操作,但由于codis本身不支持 watch 方法。所以使用codis不能完全體驗隊列功能:延遲隊列不支持、不支持數(shù)據(jù)重跑,對線上數(shù)據(jù)比較嚴格操作謹慎使用。

laravel5.3 之后redis隊列 開始使用lua腳本支持的隊列原子操作,它沒有使用 watch multi等操作,所以如果線上codis 支持lua的話,可以完整體驗到隊列功能。

參考文檔:

https://laravel-china.org/articles/4169/analysis-of-laravel-message-queue
http://laravelacademy.org/post/2012.html

更多關于Laravel相關內容感興趣的讀者可查看本站專題:《Laravel框架入門與進階教程》、《php優(yōu)秀開發(fā)框架總結》、《php面向對象程序設計入門教程》、《php+mysql數(shù)據(jù)庫操作入門教程》及《php常見數(shù)據(jù)庫操作技巧匯總》

希望本文所述對大家基于Laravel框架的PHP程序設計有所幫助。

您可能感興趣的文章:
  • laravel5.6 框架郵件隊列database驅動簡單demo示例
  • Laravel使用Queue隊列的技巧匯總
  • Docker部署Laravel應用實現(xiàn)隊列&任務調度
  • Laravel 6 將新增為指定隊列任務設置中間件的功能
  • Laravel 隊列使用的實現(xiàn)
  • Laravel中為什么不使用blpop取隊列詳析
  • 關于 Laravel Redis 多個進程同時取隊列問題詳解
  • 源碼分析 Laravel 重復執(zhí)行同一個隊列任務的原因
  • Laravel使用消息隊列需要注意的一些問題
  • Laravel中利用隊列發(fā)送郵件的方法示例
  • 淺談Laravel隊列實現(xiàn)原理解決問題記錄
  • 淺析Laravel5中隊列的配置及使用
  • PHP的Laravel框架中使用消息隊列queue及異步隊列的方法
  • Laravel 4.2 中隊列服務(queue)使用感受
  • Laravel框架中隊列和工作(Queues、Jobs)操作實例詳解

標簽:棗莊 衡水 廣元 衢州 大理 蚌埠 江蘇 萍鄉(xiāng)

巨人網絡通訊聲明:本文標題《Laravel框架隊列原理與用法分析》,本文關鍵詞  ;如發(fā)現(xiàn)本文內容存在版權問題,煩請?zhí)峁┫嚓P信息告之我們,我們將及時溝通與處理。本站內容系統(tǒng)采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢

    • 400-1100-266