Laravel 4.2 中队列服务(queue)使用感受
这半个月,我参与重写了一个微信公众号后端系统,首次使用了laravel4.2,以及laravel引以为傲的队列服务(queue)。
由于整个系统涉及到多端交互,又有大量语音传输、处理的业务,我们在一些地方发现响应时间过长。之前的系统基于node.js和mongoDB,由于node天生就是异步,有守护进程,所以并没有出现过这个问题,而这次重写必然要引入异步流程了。Queue进入了我们的视线。
根据这一页几乎还全是英文的”中文文档“,laravel恰好在4.2版本中刚刚引入了redis作为队列存储,这是一个非常好的消息。OK,背景介绍到这里,下面扯扯干货。
laravel中的队列服务跟其他队列服务也没有什么不同,都是最符合人类思维的最简单最普遍的流程:有一个地方存放队列信息,一个PHP进程在运行时将任务写入,另外一个PHP守护进程轮询队列信息,将达到执行要求的任务执行并删除。由于PHP是url驱动的同步语言,本身是阻塞的,所以laravel提供一个守护进程工具来查询并执行队列信息也就不足为奇了。
Laravel的queue配置文件是/app/config/queue.php,在DefaultQueueDriver这一项中,可以选择"sync","beanstalkd","sqs","iron","redis"五种驱动器。
1.sync是本地调试用的同步驱动器
2.beanstalkd是一个专业队列服务驱动器:http://kr.github.io/beanstalkd/
3.sqs和iron是国外第三方队列服务
4.最后一项redis给了我们一个使用redis的理由,这样我们顺便把缓存服务和session服务全部迁移到redis上了。
0.顺便说一句,session驱动器千万别用mysql,处理时间1S不是梦,哎,看谁呢,说的就是你,1S哥!
队列服务需要专门新建任务类,作为独立类,他们不需要继承类,因为队列里的任务在执行的时候,是由PHP守护进程来独立调用的,当然如果你要use一下别的类再调用,也不会出错。之前我把很多额外服务独立到了一个单独的文件夹/app/services里,比如输入信息验证validator,特殊安全验证模块等,这次queue类们就位于其中。
queue的使用非常简单,下面就是一个简单的示例:
useQueue; Queue::push('CurlJsonQueue',[ 'url'=>$url, 'json'=>$json ]);
这就是一个标准的queue压入流程了。当然,在这里我把CurlJsonQueue类放到了services根目录下,这个目录已经被我注册到composer.json的"autoload"的"classmap"中,是位于顶层命名空间中的,可以直接调用,如果需要调用非顶层命名空间,是可以写App\OOXX的。我们的系统需要大量和微信服务器交互,所以就独立出来了这个类。
<?php
classCurlJsonQueueextendsBaseController{
publicfunctionfire($job,$data) { $url=$data['url']; $json=$data['json'];
parent::base_post_curl($url,$json);
$job->delete(); } }