加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

PHP编程:Laravel 4.2 中队列服务(queue)使用感受

发布时间:2020-12-14 19:51:26 所属栏目:大数据 来源:网络整理
导读:《Laravel 4.2 中队列服务(queue)使用感受》要点: 本文介绍了Laravel 4.2 中队列服务(queue)使用感受,希望对您有用。如果有疑问,可以联系我们。 这半个月,我介入重写了一个微信公众号后端系统,首次使用了laravel 4.2,以及laravel引以为傲的队列服务(q

《Laravel 4.2 中队列服务(queue)使用感受》要点:
本文介绍了Laravel 4.2 中队列服务(queue)使用感受,希望对您有用。如果有疑问,可以联系我们。

这半个月,我介入重写了一个微信公众号后端系统,首次使用了laravel 4.2,以及laravel引以为傲的队列服务(queue).PHP学习

由于整个系统涉及到多端交互,又有大量语音传输、处理的业务,我们在一些地方发现响应时间过长.之前的系统基于node.js和mongoDB,由于node天生便是异步,有守护进程,所以并没有出现过这个问题,而这次重写必然要引入异步流程了.Queue进入了我们的视线.

根据这一页几乎还全是英文的”中文文档“,laravel恰好在4.2版本中刚刚引入了redis作为队列存储,这是一个非常好的消息.OK,配景介绍到这里,下面扯扯干货.

laravel中的队列服务跟其他队列服务也没有什么不同,都是最符合人类思维的最简单最普遍的流程:有一个地方存放队列信息,一个PHP进程在运行时将任务写入,另外一个PHP守护进程轮询队列信息,将达到执行要求的任务执行并删除.由于PHP是url驱动的同步语言,自己是阻塞的,所以laravel提供一个守护进程工具来查询并执行队列信息也就不足为奇了.

Laravel的queue配置文件是 /app/config/queue.php,在 Default Queue Driver 这一项中,可以选择"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的使用非常简单,下面便是一个简单的示例:

代码如下:

use Queue;
Queue::push('CurlJsonQueue',[
?'url' => $url,
?'json' => $json
]);

这就是一个标准的queue压入流程了.当然,在这里我把CurlJsonQueue类放到了services根目录下,这个目录已经被我注册到composer.json的"autoload"的"classmap"中,是位于顶层命名空间中的,可以直接调用,如果必要调用非顶层命名空间,是可以写 AppOOXX 的.我们的系统必要大量和微信服务器交互,所以就独立出来了这个类.

代码如下:

<?php

class CurlJsonQueue extends BaseController{

?public function fire($job,$data)
?{
??$url = $data['url'];
??$json = $data['json'];

??parent::base_post_curl($url,$json);

??$job->delete();
?}
}

这个类默认的办法是 fire(),参数也是固定的两个 $job 和 $data,由于我在BaseController中封装了post的curl模块,所以就调用了一下.另外这里还有一个小坑,当时写base_post_curl() 的时候用的protected,导致use BaseController无效,必须继承.

通过执行上面的代码,queue中就被放入了一个新的任务,laravel通过下面的命令开启守护进程:

代码如下:

php artisan queue:listen

然后守护进程就开始处置队列了.此代码中的PHP命令和artisan文件的路径请自行调整.

大家可能注意到了,我们要使用的这个队列系统用到了redis和PHP命令行,如果在测试环境,加个开机启动甚至是手动启动都可以,但是在生产环境就必要更稳固的工具来守护这两个程序,我们用的是supervisor,关于supervisor的安装配置大家可以参考这篇文章: http://blog.segmentfault.com/qianfeng/1190000000532561 注意,文章里有小坑请自行去踩...

OK,全部配置好之后,跑起来redis和PHP命令行,整个系统就开始愉快地运行啦~

使用感受:

队列服务超好用,之前一次和app的交互流程必要6-7S,异步以后降低到2S以内,基本就是传输时间和PHP代码运行时间了,耗时的特殊操作已经异步了.不过队列服务默认1S开一个进程检查一次redis中有没有可以运行的服务,在阿里云服务器上,大约能占到单核的10%,消耗略大,而且队列处理时间相对较长,因为没有了之前同步时候的文件加载福利.不过如果有多个任务,PHP进程是会连续执行的,不会1S执行一个的啦.

下面说说坑:

1. 由于queue核心类使用了一个特殊函数,导致没有明确类型的变量会以单元素数组的形式存进json,再存进redis.解决方法就是在每一个要放进去的数据前面加上 ''. .上面的$url和$json由于都已经在前面用引号进行了类型申明,故没做这一步操作.

2. 如果要传递url给队列,系统queue类会在每一个 / 前面加上两个 .这对于一些特殊操作可能会造成致命影响.(开打趣,有上面那个致命么!)

编程之家培训学院每天发布《Laravel 4.2 中队列服务(queue)使用感受》等实战技能,PHP、MYSQL、LINUX、APP、JS,CSS全面培养人才。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读