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 相关文章推荐
用Flash图形化数据(二)
Oct 09 PHP
PHP与MySQL开发中页面出现乱码的一种解决方法
Jul 29 PHP
基于php split()函数的用法详解
Jun 05 PHP
美图秀秀web开放平台--PHP流式上传和表单上传示例分享
Jun 22 PHP
php生成圆角图片的方法
Apr 07 PHP
yii2.0实现验证用户名与邮箱功能
Dec 22 PHP
PHP中file_exists使用中遇到的问题小结
Apr 05 PHP
总结PHP中DateTime的常用方法
Aug 11 PHP
php多文件打包下载的实例代码
Jul 12 PHP
Yii2.0使用阿里云OSS的SDK上传图片、下载、删除图片示例
Sep 20 PHP
php-fpm.conf配置文件中文说明详解及重要参数说明
Oct 10 PHP
微信公众号实现扫码获取微信用户信息(网页授权)
Apr 09 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
Laravel 5.1 on SAE环境开发教程【附项目demo源码】
2016/10/09 PHP
jQuery 可以拖动的div实现代码 脚本之家修正版
2009/06/26 Javascript
利用JS重写Cognos右键菜单的实现代码
2010/04/11 Javascript
非常强大的 jQuery.AsyncBox 弹出对话框插件
2011/08/29 Javascript
jQuery控制输入框只能输入数值的小例子
2013/03/20 Javascript
将HTML的左右尖括号等转义成实体形式的两种实现方式
2014/05/04 Javascript
jQuery源码分析之jQuery中的循环技巧详解
2014/09/06 Javascript
JavaScript实现的浮动层框架用法实例分析
2015/10/10 Javascript
举例说明如何为JavaScript的方法参数设置默认值
2015/11/17 Javascript
AngularJS中一般函数参数传递用法分析
2016/11/22 Javascript
JS中传递参数的几种不同方法比较
2017/01/20 Javascript
前端开发必知的15个jQuery小技巧
2017/01/22 Javascript
JavaScript html5利用FileReader实现上传功能
2020/03/27 Javascript
微信小程序实战之顶部导航栏(选项卡)(1)
2020/06/19 Javascript
简单了解Ajax表单序列化的实现方法
2019/06/14 Javascript
Js通过AES加密后PHP用Openssl解密的方法
2019/07/12 Javascript
使用preload预加载页面资源时注意事项
2020/02/03 Javascript
vue实现动态表格提交参数动态生成控件的操作
2020/11/09 Javascript
Python语言的12个基础知识点小结
2014/07/10 Python
python 列表输出重复值以及对应的角标方法
2019/06/11 Python
Django Form 实时从数据库中获取数据的操作方法
2019/07/25 Python
python制作抽奖程序代码详解
2021/01/15 Python
python time.strptime格式化实例详解
2021/02/03 Python
Python中的流程控制详解
2021/02/18 Python
html5 跨文档消息传输示例探讨
2013/04/01 HTML / CSS
HTML5手指下滑弹出负一屏阻止移动端浏览器内置下拉刷新功能的实现代码
2020/04/10 HTML / CSS
三维科技面试题
2013/07/27 面试题
六年级数学教学反思
2014/02/03 职场文书
2014年教师节演讲稿
2014/09/03 职场文书
2014年信息宣传工作总结
2014/12/18 职场文书
二年级学生期末评语
2014/12/26 职场文书
十二生肖观后感
2015/06/12 职场文书
标会主持词应该怎么写?
2019/08/15 职场文书
一个成功的互联网创业项目,必须满足这些要求
2019/08/23 职场文书
Mysql将字符串按照指定字符分割的正确方法
2022/05/30 MySQL
MySql如何将查询的出来的字段进行转换
2022/06/14 MySQL