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 服务器配置(使用Apache及IIS两种方法)
Jun 01 PHP
2014过年倒计时示例
Jan 31 PHP
PHP中使用匿名函数操作数据库的例子
Nov 17 PHP
PHP PDOStatement对象bindpram()、bindvalue()和bindcolumn之间的区别
Nov 20 PHP
用php代码限制国内IP访问我们网站
Sep 26 PHP
2款PHP无限级分类实例代码
Nov 11 PHP
PHP数组函数array_multisort()用法实例分析
Apr 02 PHP
利用switch语句进行多选一判断的实例代码
Nov 14 PHP
Zend Framework框架中实现Ajax的方法示例
Jun 27 PHP
PHP封装curl的调用接口及常用函数详解
May 31 PHP
php将从数据库中获得的数据转换成json格式并输出的方法
Aug 21 PHP
laravel框架使用阿里云短信发送消息操作示例
Feb 15 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开发入门教程之面向对象
2006/12/05 PHP
如何使用PHP计算上一个月的今天
2013/05/23 PHP
解析linux下安装memcacheq(mcq)全过程笔记
2013/06/27 PHP
php对二维数组进行相关操作(排序、转换、去空白等)
2015/11/04 PHP
WordPress中用于获取搜索表单的PHP函数使用解析
2016/01/05 PHP
php格式化时间戳
2016/12/17 PHP
用AJAX返回HTML片段中的JavaScript脚本
2010/01/04 Javascript
该如何加载google-analytics(或其他第三方)的JS
2010/05/13 Javascript
在javascript中实现函数数组的方法
2013/12/25 Javascript
node.js中RPC(远程过程调用)的实现原理介绍
2014/12/05 Javascript
javascript为按钮注册回车事件(设置默认按钮)的方法
2015/05/09 Javascript
快速学习JavaScript的6个思维技巧
2015/10/13 Javascript
js实现简单的验证码
2015/12/25 Javascript
JavaScript与jQuery实现的闪烁输入效果
2016/02/18 Javascript
Vue.js 2.x之组件的定义和注册图文详解
2018/06/19 Javascript
vue项目打包后打开页面空白解决办法
2018/06/29 Javascript
微信小程序自定义组件封装及父子间组件传值的方法
2018/08/28 Javascript
vue+canvas实现炫酷时钟效果的倒计时插件(已发布到npm的vue2插件,开箱即用)
2018/11/05 Javascript
javaScript实现游戏倒计时功能
2018/11/17 Javascript
D3.js(v3)+react 实现带坐标与比例尺的柱形图 (V3版本)
2019/05/09 Javascript
ES6顶层对象、global对象实例分析
2019/06/14 Javascript
js实现随机div颜色位置 类似满天星效果
2019/10/24 Javascript
原生javascript单例模式的应用实例分析
2020/02/23 Javascript
如何使用原生Js实现随机点名详解
2021/01/06 Javascript
Python中的闭包详细介绍和实例
2014/11/21 Python
Python实现设置windows桌面壁纸代码分享
2015/03/28 Python
Python中用sleep()方法操作时间的教程
2015/05/22 Python
对numpy中的数组条件筛选功能详解
2018/07/02 Python
Python实现FM算法解析
2019/06/18 Python
PyQt+socket实现远程操作服务器的方法示例
2019/08/22 Python
浅谈matplotlib默认字体设置探索
2021/02/03 Python
canvas实现烟花的示例代码
2020/01/16 HTML / CSS
初中考试作弊检讨书
2014/02/01 职场文书
行政专员岗位职责说明书
2014/09/01 职场文书
推广普通话的宣传语
2015/07/13 职场文书
Python机器学习应用之基于线性判别模型的分类篇详解
2022/01/18 Python