Laravel使用消息队列需要注意的一些问题


Posted in PHP onDecember 13, 2017

前言

消息队列对于大型的Web项目来说是必不可少的一个模块,通过消息队列可以解决大并发和多种语言通信接口等问题。对于大并发的问题,可以将耗时的任务或者不能同时大量并行的任务封装起来传输到消息队列中,由处理程序不断从消息队列中提取消息并进行处理,这样通过消息队列的缓冲可以使得在大并发情况下不再阻塞,如果性能不够用还可以添加多个处理任务从消息队列中获取消息进行处理。比如数据库的操作,当对数据库的读、写操作过多时就会存在锁表等问题,读的问题可以通过缓存等方案解决,写的问题就需要消息队列来解决。而且,在大型的Web项目开发中,很多情况下不可能通过一种语言实现,需要发挥不同语言的优势,比如PHP,虽然在理论意义上它可以做Web开发中的所有事情,但是有些问题用它解决效率将会非常低,比如实时socket连接和分布式事务处理等。

使用 Laravel 的消息队列处理异步任务,Redis 作为队列数据库,Supervisor 监控脚本异常中断并自动重启,这是 Laravel 处理队列任务的标准流程,但是实际中可能还会出现各种各样的问题,为了保证系统可靠性,还要注意几个问题。

一、执行失败重试次数设置

一定要设置任务执行失败重试次数,避免无限失败重试,超过重试次数 Laravel 会默认写到失败任务表中,也可以自己写执行失败后续处理逻辑。

php artisan queue:work redis --tries=3

需要先执行以下命令创建数据表:

php artisan queue:failed-table
php artisan migrate

二、程序异常的处理

有时候程序执行过程会发生异常,比如依赖其他接口,请求 HTTP 接口超时等等,如果不捕捉异常,那么当前这个队列就会中断不能继续运行下去,比如给 10000 个用户推送内容,需要依赖接口推送,如果中间的请求挂了就会影响到后面的推送。

这里的异常是指程序执行过程中发生的异常,不是指常驻进程挂掉,程序异常不一定导致常驻进程中断,况且进程中断有 Supervisor 监控并重启。

如捕获异常代码片段:

try {
 $r = $client->request('POST', '', [
  'query' => [
   'client_name'  => 'filemail',
   'client_version' => '1.0',
   'client_sequence' => 0,
   'uid'    => 692934013,//119481237
   'r'    => 1508312484,
  ],
  'body' => \GuzzleHttp\json_encode($body),
 ]);
 $result = $r->getBody()->getContents();
 $result = json_decode($result, true);
 if ($result['result'] == 0) {
  info("sendMail fail:" . json_encode($result));
  $this->pushLog($task['id'], $task['mail_id'], implode(',', $userIds), json_encode($result), 0);
 } else {
  Log::warning("sendMail fail:" . json_encode($result));
  $this->pushLog($task['id'], $task['mail_id'], implode(',', $userIds), json_encode($result), $result['result']);
 }
} catch (RequestException $e) {
 Log::warning('RequestException' . $e->getMessage());
} catch (Exception $e) {
 Log::emergency('Exception' . $e->getMessage());
}

三、修改代码记得重启 Supervisor

最后一点,修改了处理队列的程序,记得要重启 Supervisor,否则脚本不会生效。

Laravel 往 Redis 写队列的数据结构

队列用 list 类型存储,如图:

Laravel使用消息队列需要注意的一些问题 

value 内容如下:

{
 "job": "Illuminate\\Queue\\CallQueuedHandler@call",
 "data": {
 "commandName": "App\\Jobs\\SendFile",
 "command": "O:17:\"App\\Jobs\\SendFile\":5:{s:23:\"\u0000App\\Jobs\\SendFile\u0000task\";a:8:{s:5:\"title\";s:4:\"1111\";s:4:\"note\";s:2:\"11\";s:6:\"reward\";s:0:\"\";s:7:\"mail_id\";s:5:\"66681\";s:4:\"nums\";i:20;s:8:\"uid_file\";s:33:\"uidfile\/file-66681-1513058185.txt\";s:5:\"gcids\";s:40:\"1B9DD95645AAE8119F7DA9B9FF738D52BC8A1BD5\";s:2:\"id\";i:29;}s:6:\"\u0000*\u0000job\";N;s:10:\"connection\";N;s:5:\"queue\";s:8:\"sendfile\";s:5:\"delay\";N;}"
 },
 "id": "l0mjsUthbxm4TgIJNUH13km9N8DIpErK",
 "attempts": 1
}

包含失败重试次数,队列标识,处理队列的类,以及队列的数据等等。

参考链接

Laravel 官方文档 Queue 队列:

https://laravel.com/docs/5.5/queues

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

PHP 相关文章推荐
PHP新手上路(四)
Oct 09 PHP
php Mysql日期和时间函数集合
Nov 16 PHP
可以在线执行PHP代码包装修正版
Mar 15 PHP
php多用户读写文件冲突的解决办法
Nov 06 PHP
ThinkPHP实现非标准名称数据表快速创建模型的方法
Nov 29 PHP
PHP贪婪算法解决0-1背包问题实例分析
Mar 23 PHP
php使用GD库创建图片缩略图的方法
Jun 10 PHP
PHP更安全的密码加密机制Bcrypt详解
Jun 18 PHP
解决安装WampServer时提示缺少msvcr110.dll文件的问题
Jul 09 PHP
php+mysql开发的最简单在线题库(在线做题系统)完整案例
Mar 30 PHP
解决php用mysql方式连接数据库出现Deprecated报错问题
Dec 25 PHP
Laravel5.1 框架Middleware中间件基本用法实例分析
Jan 04 PHP
实例分析PHP中PHPMailer发邮件
Dec 13 #PHP
使用XHProf查找PHP性能瓶颈的实例
Dec 13 #PHP
PHP让数组中有相同值的组成新的数组实例
Dec 31 #PHP
详谈PHP中public,private,protected,abstract等关键字的用法
Dec 31 #PHP
php中通用的excel导出方法实例
Dec 30 #PHP
利用Laravel生成Gravatar头像地址的优雅方法
Dec 30 #PHP
PHP如何实现订单的延时处理详解
Dec 30 #PHP
You might like
PHP stristr() 函数(不区分大小写的字符串查找)
2010/06/03 PHP
php实现URL加密解密的方法
2016/11/17 PHP
PHP钩子与简单分发方式实例分析
2017/09/04 PHP
Javascript条件判断使用小技巧总结
2008/09/08 Javascript
Microsoft Ajax Minifier 压缩javascript的方法
2010/03/05 Javascript
JavaScript 操作键盘的Enter事件(键盘任何事件),兼容多浏览器
2010/10/11 Javascript
javascript学习笔记(二) js一些基本概念
2012/06/18 Javascript
jquery中使用$(#form).submit()重写提交表单无效原因分析及解决
2013/03/25 Javascript
javascript动态添加样式(行内式/嵌入式/外链式等规则)
2013/06/24 Javascript
显示今天的日期js代码(阳历和农历)
2014/09/30 Javascript
《JavaScript DOM 编程艺术》读书笔记之JavaScript 图片库
2015/01/09 Javascript
jQuery中innerWidth()方法用法实例
2015/01/19 Javascript
教你用javascript实现随机标签云效果_附代码
2016/03/16 Javascript
jQuery实现磁力图片跟随效果完整示例
2016/09/16 Javascript
BootStrap树状图显示功能
2016/11/24 Javascript
js面向对象编程总结
2017/02/16 Javascript
Angular.js自动化测试之protractor详解
2017/07/07 Javascript
[55:23]VGJ.T vs Winstrike 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/20 DOTA
[56:48]FNATIC vs EG 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/16 DOTA
python学习之第三方包安装方法(两种方法)
2015/07/30 Python
Python正则表达式教程之三:贪婪/非贪婪特性
2017/03/02 Python
Python生成8位随机字符串的方法分析
2017/12/05 Python
numpy中实现二维数组按照某列、某行排序的方法
2018/04/04 Python
python 以16进制打印输出的方法
2018/07/09 Python
python实现图片中文字分割效果
2019/07/22 Python
pytorch使用tensorboardX进行loss可视化实例
2020/02/24 Python
python GUI库图形界面开发之PyQt5开发环境配置与基础使用
2020/02/25 Python
Python离线安装各种库及pip的方法
2020/11/28 Python
CSS3截取字符串实例代码【推荐】
2018/06/07 HTML / CSS
使用iframe+postMessage实现页面跨域通信的示例代码
2020/01/14 HTML / CSS
亚马逊新加坡官方网站:Amazon.sg
2020/03/25 全球购物
日本最大的彩色隐形眼镜销售网站:CharmColor
2020/09/09 全球购物
小学运动会口号
2014/06/07 职场文书
世博会口号
2014/06/20 职场文书
你有一份《诚信考试承诺书》待领取
2019/11/13 职场文书
MySQL大小写敏感的注意事项
2021/05/24 MySQL