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 相关文章推荐
我常用的几个类
Oct 09 PHP
动态新闻发布的实现及其技巧
Oct 09 PHP
dedecms采集中可以过滤多行代码的正则表达式
Mar 17 PHP
注册页面之前先验证用户名是否存在的php代码
Jul 14 PHP
基于php和mysql的简单的dao类实现crud操作功能
Jan 27 PHP
PHP生成迅雷、快车、旋风等软件的下载链接代码实例
May 12 PHP
CodeIgniter辅助之第三方类库third_party用法分析
Jan 20 PHP
PHP中的Trait 特性及作用
Apr 03 PHP
PHP中Cookie的使用详解(简单易懂)
Apr 28 PHP
PHP实现驼峰样式字符串(首字母大写)转换成下划线样式字符串的方法示例
Aug 10 PHP
PHP静态方法和静态属性及常量属性的区别与介绍
Mar 22 PHP
PHP手机号码及邮箱正则表达式实例解析
Jul 11 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
WordPress中用于获取文章信息以及分类链接的函数用法
2015/12/18 PHP
PHP简单实现正则匹配省市区的方法
2018/04/13 PHP
Laravel框架实现简单的学生信息管理平台案例
2019/05/07 PHP
php封装的pdo数据库操作工具类与用法示例
2019/05/08 PHP
PHP大文件切割上传并带进度条功能示例
2019/07/01 PHP
jQuery搜索同辈元素方法
2015/02/10 Javascript
JavaScript函数详解
2015/02/27 Javascript
如何实现chrome浏览器关闭页面时弹出“确定要离开此面吗?”
2015/03/05 Javascript
jquery dialog获取焦点的方法
2017/02/09 Javascript
详解vue组件通信的三种方式
2017/06/30 Javascript
jQuery实现左右两个列表框的内容相互移动功能示例
2019/01/27 jQuery
js继承的这6种方式!(上)
2019/04/23 Javascript
js模拟F11页面全屏显示
2019/09/17 Javascript
vue 导航内容设置选中状态样式的例子
2019/11/01 Javascript
vue中父子组件传值,解决钩子函数mounted只运行一次的操作
2020/07/27 Javascript
详解JavaScript中的链式调用
2020/11/27 Javascript
Python获取文件ssdeep值的方法
2014/10/05 Python
python登陆asp网站页面的实现代码
2015/01/14 Python
Python实现统计英文文章词频的方法分析
2019/01/28 Python
selenium+python环境配置教程详解
2019/05/28 Python
基于python计算滚动方差(标准差)talib和pd.rolling函数差异详解
2020/06/08 Python
HTML5 CSS3实现一个精美VCD包装盒个性幻灯片案例
2014/06/16 HTML / CSS
美国医生配方营养补充剂供应商:Healthy Directions
2019/07/10 全球购物
Wedgwood英国官方网站:英式精致骨瓷餐具、礼品与生活精品,源于1759年
2019/09/02 全球购物
德国户外装备、登山运动和攀岩商店:tapir store
2020/02/12 全球购物
青年教师培训方案
2014/02/06 职场文书
施工安全责任书
2014/04/14 职场文书
小学生中国梦演讲稿
2014/04/23 职场文书
森林病虫害防治方案
2014/06/02 职场文书
大学新闻系求职信
2014/06/03 职场文书
党员自我评价2015
2015/03/03 职场文书
感恩父母主题班会
2015/08/12 职场文书
旷工检讨书大全
2015/08/15 职场文书
导游词之张家界
2019/10/31 职场文书
Python下opencv使用hough变换检测直线与圆
2021/06/18 Python
Python+Tkinter制作专属图形化界面
2022/04/01 Python