Laravel框架队列原理与用法分析

前端之家收集整理的这篇文章主要介绍了Laravel框架队列原理与用法分析前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

本文实例讲述了Laravel框架队列原理与用法分享给大家供大家参考,具体如下:

最近有朋友有朋友问laravel队列的实现原理和经验,刚好用过所以整理了一下分享给大家。

laravel队列配置参见:

原理分析

创建分发任务方法

dispatch((new SendMessage($sendParams))->onQueue('snail:SendMessage')); } }

内部实现:

创建消费任务

命令行运行如下命令:

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

内部实现:

队列消息分析:

监控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]

解决方法修改PHP

[ 'driver' => 'redis','connection' => 'default','queue' => 'default','expire' => null,//禁用即可 ],

优化日志处理:

如果你的系统有切割文件日志操作。会发现虽然日志被切分了,但程序却没有往新文件里写入。如,2017-04-18 13:50启动的项目,日志会一直打到 snail.log.2017041813上。

改进方案:

PHP文件添加如下方法

getHandlers(); if(!is_array($handles) || empty($handles)){ return; } foreach($handles as $handle){ if(method_exists($handle,"close")){ $handle->close(); } } return; }

在具体job实现类中的handle方法结尾添加

releaseLoggerFile(); //释放log文件 }

线上部署

创建任务shell

> $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的话,可以完整体验到队列功能

参考文档:

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

更多关于Laravel相关内容感兴趣的读者可查看本站专题:《》、《》、《》、《》及《PHP常见数据库操作技巧汇总》

希望本文所述对大家基于Laravel框架的PHP程序设计有所帮助。

原文链接:https://www.f2er.com/laravel/15707.html

猜你在找的Laravel相关文章