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 相关文章推荐
PHPMailer邮件类利用smtp.163.com发送邮件方法
Sep 11 PHP
php结合表单实现一些简单功能的例子
Jun 04 PHP
深入php处理整数函数的详解
Jun 09 PHP
限制ckeditor上传图片文件大小的方法
Nov 15 PHP
php使用GeoIP库实例
Jun 27 PHP
PHP-Java-Bridge使用笔记
Sep 22 PHP
php获取json数据所有的节点路径
May 17 PHP
PHP实现文件上传和多文件上传
Dec 24 PHP
php使用pear_smtp发送邮件
Apr 15 PHP
解决PHP程序运行时:Fatal error: Maximum execution time of 30 seconds exceeded in的错误提示
Nov 25 PHP
Laravel 5.4.36中session没有保存成功问题的解决
Feb 19 PHP
php实现微信模板消息推送
Mar 30 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
PHP实现视频文件上传完整实例
2014/08/28 PHP
PHP新特性之字节码缓存和内置服务器
2017/08/11 PHP
封装的原生javascript弹出层代码
2010/09/24 Javascript
Js sort排序使用方法
2011/10/17 Javascript
Json序列化和反序列化方法解析
2013/12/19 Javascript
js使用心得分享
2015/01/13 Javascript
javascript强制点击广告的方法
2015/02/06 Javascript
ajax接收后台数据在html页面显示
2017/02/19 Javascript
Javascript中八种遍历方法的执行速度深度对比
2017/04/25 Javascript
layer弹窗插件操作方法详解
2017/05/19 Javascript
JS实现新建文件夹功能
2017/06/17 Javascript
vue.js如何更改默认端口号8080为指定端口的方法
2017/07/14 Javascript
VueRouter导航守卫用法详解
2017/12/25 Javascript
vue 搭建后台系统模块化开发详解
2019/05/01 Javascript
关于微信小程序map组件z-index的层级问题分析
2019/07/09 Javascript
微信小程序里引入SVG矢量图标的方法
2019/09/20 Javascript
vue同个按钮控制展开和折叠同个事件操作
2020/07/29 Javascript
vue项目如何监听localStorage或sessionStorage的变化
2021/01/04 Vue.js
Python的Flask框架中web表单的教程
2015/04/20 Python
Python中获取对象信息的方法
2015/04/27 Python
剖析Django中模版标签的解析与参数传递
2015/07/21 Python
python判断设备是否联网的方法
2018/06/29 Python
ubuntu 18.04搭建python环境(pycharm+anaconda)
2019/06/14 Python
Python求正态分布曲线下面积实例
2019/11/20 Python
Python 基于FIR实现Hilbert滤波器求信号包络详解
2020/02/26 Python
Python Selenium异常处理的实例分析
2021/02/28 Python
馥绿德雅美国官方网站:Rene Furterer头皮护理专家
2019/05/01 全球购物
Aosom西班牙:家具在线商店
2020/06/11 全球购物
New delete 与malloc free 的联系与区别
2013/02/04 面试题
自动化专业个人求职信范文
2013/11/29 职场文书
幼儿园安全检查制度
2014/01/30 职场文书
六查六看自查材料
2014/02/17 职场文书
演讲主持词
2014/03/18 职场文书
英文演讲稿
2014/05/15 职场文书
民主评议党员总结
2014/10/20 职场文书
MySQL数据库之存储过程 procedure
2022/06/16 MySQL