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 相关文章推荐
将RTF格式的文件转成HTML并在网页中显示的代码
Oct 09 PHP
在线增减.htpasswd内的用户
Oct 09 PHP
使用PHP的日期与时间函数技巧
Apr 24 PHP
初学CAKEPHP 基础教程
Nov 02 PHP
PHPWind与Discuz截取字符函数substrs与cutstr性能比较
Dec 05 PHP
奇怪的PHP引用效率问题分析
Mar 23 PHP
PHP会话控制:Session与Cookie详解
Sep 27 PHP
php备份数据库类分享
Apr 14 PHP
PHP 反射(Reflection)使用实例
May 12 PHP
form自动提交实例讲解
Jul 10 PHP
ThinkPHP5框架缓存查询操作分析
May 30 PHP
PHP实现爬虫爬取图片代码实例
Mar 03 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
预告映像公开!第1章续篇剧场版动画《Princess Principal Crown Handler》4月10日上映!
2020/03/06 日漫
深入理解php的MySQL连接类
2013/06/07 PHP
phpQuery占用内存过多的处理方法
2013/11/13 PHP
PHP中的reflection反射机制测试例子
2014/08/05 PHP
XMLHTTP 乱码的解决方法(UTF8,GB2312 编码 解码)
2011/01/12 Javascript
js数组转json并在后台对其解析具体实现
2013/11/20 Javascript
JS自定义对象实现Java中Map对象功能的方法
2015/01/20 Javascript
js显示文本框提示文字的方法
2015/05/07 Javascript
jQuery实现网页抖动的菜单抖动效果
2015/08/07 Javascript
js实现跨域的4种实用方法原理分析
2015/10/29 Javascript
jquery validate.js表单验证入门实例(附源码)
2015/11/10 Javascript
AngularJS 使用$sce控制代码安全检查
2016/01/05 Javascript
jQuery+css实现的时钟效果(兼容各浏览器)
2016/01/27 Javascript
JS实现复制内容到剪贴板功能兼容所有浏览器(推荐)
2016/06/17 Javascript
JavaScript自动点击链接 防止绕过浏览器访问的方法
2017/01/19 Javascript
vue-router路由简单案例介绍
2017/02/21 Javascript
Bootstrap Tooltip显示换行和左对齐的解决方案
2017/10/11 Javascript
详解处理Vue单页面应用SEO的另一种思路
2018/11/09 Javascript
JavaScript实现捕获鼠标坐标
2020/04/12 Javascript
Vue+axios封装请求实现前后端分离
2020/10/23 Javascript
python中base64加密解密方法实例分析
2015/05/16 Python
pytorch + visdom CNN处理自建图片数据集的方法
2018/06/04 Python
基于python if 判断选择结构的实例详解
2019/05/06 Python
如何利用python给图片添加半透明水印
2019/09/06 Python
tensorflow 只恢复部分模型参数的实例
2020/01/06 Python
利用python对excel中一列的时间数据更改格式操作
2020/07/14 Python
打架检讨书800字
2014/01/10 职场文书
四川成都导游欢迎词
2014/01/18 职场文书
求职个人评价范文
2014/04/09 职场文书
专科应届毕业生求职信
2014/06/04 职场文书
学校工作推荐信范文
2014/07/11 职场文书
上课说话检讨书500字
2014/11/01 职场文书
优秀教师个人材料
2014/12/15 职场文书
详解运行Python的神器Jupyter Notebook
2021/06/03 Python
python实现剪贴板的操作
2021/07/01 Python
Python IO文件管理的具体使用
2022/03/20 Python