溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Laravel框架中隊列的原理是什么

發布時間:2021-05-10 17:22:39 來源:億速云 閱讀:1116 作者:Leah 欄目:開發技術

本篇文章為大家展示了Laravel框架中隊列的原理是什么,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

Laravel 是什么

Laravel 是一套簡潔、優雅的PHP Web開發框架。它可以讓你從面條一樣雜亂的代碼中解脫出來;它可以幫你構建一個完美的網絡APP,而且每行代碼都可以簡潔、富于表達力。

原理分析

創建分發任務方法

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

內部實現:

Laravel框架中隊列的原理是什么

創建消費任務

命令行運行如下命令:

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

內部實現:

Laravel框架中隊列的原理是什么

隊列消息分析:

監控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

所以執行消費任務會有以下錯誤:

[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,  //禁用即可
],

優化日志處理:

如果你的系統有切割文件日志操作。會發現雖然日志被切分了,但程序卻沒有往新文件里寫入。如,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實現類中的handle方法結尾添加:

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

線上部署

創建任務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不能完全體驗隊列功能:延遲隊列不支持、不支持數據重跑,對線上數據比較嚴格操作謹慎使用。

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

上述內容就是Laravel框架中隊列的原理是什么,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女