PHP的Laravel框架中使用消息队列queue及异步队列的方法


Posted in PHP onMarch 21, 2016

queue配置

首先说明一下我之前的项目中如何使用queue的。

我们现在的项目都是用的symfony,老一点的项目用的symfony1.4,新一点的项目用的都是symfony2。symfony用起来整体感觉还是很爽的,尤其symfony2,整体上来讲使用了很多java里面框架的设计思想。但是他不支持queue。在symfony,我们使用queue也经历了几个过程。最开始使用张堰同学的httpsqs。这个简单使用,但是存在单点。毕竟我们的项目还是正式对外服务的,所以我们研究了Apache旗下的开源项目ActiveMQ,研究研究发现还有Apache旗下还有更新的MQ,那就是Apollo。最后我们决定使用的Apollo。

queue在我们的项目中主要的应用场景就是异步处理一些比较耗时的功能,比如同步第三方数据、数据有变动了同步通知到我们的第三方数据使用者等等。我们大致的思路是这样的,在各个controller里面如果需要异步处理的,就把一个json对象encode一下,塞到Apollo里面。再写一个work的Command,在这个Command中解析json对象,根据里面的action和参数决定来调用不同的方法处理。根据业务需要同时在不同的机器上运行Command作为守护进程一直跑着,也算实现异步多任务处理应用的方案。就这么一直使用着,直到发现了laravel。打算研究一下。如果可能替代一下也不是不可能。呵呵。

由于才开始学习,当然直接上laravel5。routes、controller、view都基本上和symfony差别不到,上手倒是不困难。最后研究一下queue。

1、安装laravle,使用composer,倒是很简单。

composer global require "laravel/installer=~1.1"
vi ~/.bash_profile

把~/.composer/vendor/bin 加入到环境变量中。

source ~/.bash_profile

就可以直接在命令行中使用laravel了。试一下。

laravel -V

能够看到下面的,就代表成功了。

Laravel Installer version 1.2.1

2、创建项目。

laravel new guagua

3、配置redis和queue。

4、创建controller,

php artisan make:controller DefaultController

在controller的action中push100个queue的任务。

for($i = 0; $i < 100; $i ++) {
  Queue::push(new SendEmail("ssss".$i));
}

5、创建queue的Command

php artisan make:command SendEmail --queued

修改app/Commands/SendEmail.php,添加一个私有变量。

protected $msg;

同时修改构造函数。

public function __construct($msg)
{
  $this->msg = $msg;
}

再修改的handle方法

public function handle() {
  sleep(4);
  echo $this->msg."\t".date("Y-m-d H:i:s")."\n";
  $this->delete();
}

6、修改routes

Route::get('/', [
  'as' => 'index',
  'uses' => 'DefaultController@index'
]);

7、监听queue

php artisan queue:listen

为了验证多任务处理,我们同时开三个窗口运行同样的命令。

8、用laravel内建的server启动服务

php artisan serve --port 8080

打开浏览器,访问http://localhost:8080/页面。当然也可以用nginx,apache之类的。但是需要各种配置,还是内建的使用方便。

在控制台就能看到各个queue执行的情况了,如下图。可以看到100个任务被三个work平分了。

PHP的Laravel框架中使用消息队列queue及异步队列的方法

到此,基本达到了我想要的效果。验证了laravel可以简单实现queue,并且可以多任务处理。

make command生成的代码中use App\Commands\Command ,但是运行时提示没有这个文件。 解决办法,修改为 use Illuminate\Console\Command; 不知道为什么会出现这个低级问题,难道是我mac系统问题,还是我的人品问题。
在controller的action中push队列的时候,没有异步执行,还是在action的脚本中执行的。 发现是配置问题,原来不仅仅要修改config中的queue.php,还要修改.evn中相关配置。 虽然问题解决了,但是还是觉得蛋疼,不能理解。还需要在学习学习laravel。

异步队列使用方法

1.配置

关于队列的定义,这里就不作介绍了。我们要使用异步队列就有两个关键:

(1)存储队列的地方
(2)执行任务的服务
打开 config/queue.php ,这是Laravel5关于队列的配置文件。首先我们可以通过 default 参数指定默认队列驱动,默认配置是 sync , 这是同步队列,我们要做异步队列首先就要改变这里。假设我们用 database 作为驱动,队列任务将会存放在数据库中,而我们后面会另外启动一个后台服务来处理队列任务,这就是异步方式了。

'default' => 'database'

修改完配置后,我们需要创建一个表来存放队列任务,Laravel5已经在自带artisan命令中内置了一个指令用来生成数据迁移,只需要两条命令即可,当然你得实现配置好数据库连接。

php artisan queue:table
php artisan migrate

这样就自动在数据库中创建了 jobs 表。

2.启动队列监听服务

通过下面这条指令启动队列监听服务,它会自动处理 jobs 表中的队列任务:

php artisan queue:listen

在linux中,如果想让它在后台执行,可以这样:

nohup php artisan queue:listen &

3.添加队列任务

关于队列任务的添加,手册里说的比较详细,这里就简单举个例子吧。

首先,通过artisan创建一个队列命令:

php artisan make:command SendEmail --queued

这样会生成 app/Commands/SendEmail.php 这个类文件,这个类会被标识为队列命令,你可以在 handle 方法中写自己的业务逻辑。

在控制器中,可以简单通过 Bus::dispatch 分发任务:

Bus::dispatch(new \App\Commands\SendEmail());

你会发现任务不会立即执行,而是被放到 jobs 表中,由队列监听服务处理。

更详细的用法建议参考 command bus 和 queue 相关的手册章节。

PHP 相关文章推荐
php下检测字符串是否是utf8编码的代码
Jun 28 PHP
php下利用curl判断远程文件是否存在的实现代码
Oct 08 PHP
php通过COM类调用组件的实现代码
Jan 11 PHP
php获取ip的三个属性区别介绍(HTTP_X_FORWARDED_FOR,HTTP_VIA,REMOTE_ADDR)
Sep 23 PHP
php使用smtp发送支持附件的邮件示例
Apr 13 PHP
Laravel 5框架学习之Eloquent 关系
Apr 09 PHP
php函数传值的引用传递注意事项分析
Jun 25 PHP
Yii2框架制作RESTful风格的API快速入门教程
Nov 08 PHP
thinkPHP框架实现的无限回复评论功能示例
Jun 09 PHP
Laravel框架运行出错提示RuntimeException No application encryption key has been specified.解决方法
Apr 02 PHP
php使用pecl方式安装扩展操作示例
Aug 12 PHP
Centos7安装swoole扩展操作示例
Mar 26 PHP
Zend Framework框架之Zend_Mail实现发送Email邮件验证功能及解决标题乱码的方法
Mar 21 #PHP
Zend Framework教程之Zend_Form组件实现表单提交并显示错误提示的方法
Mar 21 #PHP
Zend Framework实现多文件上传功能实例
Mar 21 #PHP
Zend Framework入门之环境配置及第一个Hello World示例(附demo源码下载)
Mar 21 #PHP
Zend Framework教程之连接数据库并执行增删查的方法(附demo源码下载)
Mar 21 #PHP
Zend Framework框架教程之Zend_Db_Table_Rowset用法实例分析
Mar 21 #PHP
Zend Framework教程之Zend_Db_Table_Row用法实例分析
Mar 21 #PHP
You might like
ThinkPHP的URL重写问题
2014/06/22 PHP
YII框架行为behaviors用法示例
2019/04/26 PHP
PHP实现将上传图片自动缩放到指定分辨率,并保持清晰度封装类示例
2019/06/17 PHP
ASP.NET jQuery 实例14 在ASP.NET form中校验时间范围
2012/02/03 Javascript
滚动条响应鼠标滑轮事件实现上下滚动的js代码
2014/06/30 Javascript
js交换排序 冒泡排序算法(Javascript版)
2014/10/04 Javascript
使用Meteor配合Node.js编写实时聊天应用的范例
2015/06/23 Javascript
js实现人民币大写金额形式转换
2016/04/27 Javascript
Angular2 (RC5) 路由与导航详解
2016/09/21 Javascript
利用jQuery插件imgAreaSelect实现获得选择域的图像信息
2016/12/02 Javascript
原生js实现打字动画游戏
2017/02/04 Javascript
Vuex模块化实现待办事项的状态管理
2017/03/15 Javascript
React Native实现进度条弹框的示例代码
2017/07/17 Javascript
基于rollup的组件库打包体积优化小结
2018/06/18 Javascript
解决vue v-for 遍历循环时key值报错的问题
2018/09/06 Javascript
Jquery 动态添加元素并添加点击事件实现过程解析
2019/10/12 jQuery
vue实现购物车加减
2020/05/30 Javascript
详解JavaScript之Array.reduce源码解读
2020/11/01 Javascript
[50:02]完美世界DOTA2联赛PWL S2 Magma vs FTD 第三场 11.29
2020/12/03 DOTA
使用实现XlsxWriter创建Excel文件并编辑
2018/05/04 Python
python实现定时提取实时日志程序
2018/06/22 Python
浅谈django orm 优化
2018/08/18 Python
微信小程序python用户认证的实现
2019/07/29 Python
python 爬取学信网登录页面的例子
2019/08/13 Python
解决python cv2.imread 读取中文路径的图片返回为None的问题
2020/06/02 Python
使用Django的JsonResponse返回数据的实现
2021/01/15 Python
关于解决iframe标签嵌套问题的解决方法
2020/03/04 HTML / CSS
奥巴马演讲稿
2014/01/08 职场文书
七一党建活动方案
2014/01/28 职场文书
教师四风自我剖析材料
2014/09/30 职场文书
2014银行授权委托书样本
2014/10/04 职场文书
督导岗位职责
2015/02/04 职场文书
大学生毕业个人总结
2015/02/15 职场文书
承诺保证书格式
2015/02/28 职场文书
南京南京观后感
2015/06/02 职场文书
2015年中秋节主持词
2015/07/30 职场文书