Lumen开发:结合Redis实现消息队列(3)
4、运行队列监听器
开启任务监听器
Lumen包含了一个Artisan命令用来运行推送到队列的新任务。你可以使用queue:listen命令运行监听器:
php artisan queue:listen
还可以指定监听器使用哪个队列连接:
php artisan queue:listen connection
注意一旦任务开始后,将会持续运行直到手动停止。你可以使用一个过程监视器如Supervisor来确保队列监听器没有停止运行。
队列优先级
你可以传递逗号分隔的队列连接列表到listen任务来设置队列优先级:
php artisan queue:listen --queue=high,low
在本例中,high队列上的任务总是在从low队列移动任务之前被处理。
指定任务超时参数
你还可以设置每个任务允许运行的最大时间(以秒为单位):
php artisan queue:listen --timeout=60
指定队列睡眠时间
此外,可以指定轮询新任务之前的等待时间(以秒为单位):
php artisan queue:listen --sleep=5
需要注意的是队列只会在队列上没有任务时“睡眠”,如果存在多个有效任务,该队列会持续运行,从不睡眠。
4.1 Supervisor配置
Supervisor为Linux操作系统提供的进程监视器,将会在失败时自动重启queue:listen或queue:work命令,要在Ubuntu上安装Supervisor,使用如下命令:
sudo apt-get install supervisor
Supervisor配置文件通常存放在/etc/supervisor/conf.d目录,在该目录中,可以创建多个配置文件指示Supervisor如何监视进程,例如,让我们创建一个开启并监视queue:work进程的laravel-worker.conf文件:
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /home/forge/app.com/artisan queue:work sqs --sleep=3 --tries=3 --daemon
autostart=true
autorestart=true
user=forge
numprocs=8
redirect_stderr=true
stdout_logfile=/home/forge/app.com/worker.log
在本例中,numprocs指令让Supervisor运行8个queue:work进程并监视它们,如果失败的话自动重启。配置文件创建好了之后,可以使用如下命令更新Supervisor配置并开启进程:
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start laravel-worker:*
要了解更多关于Supervisor的使用和配置,查看Supervisor文档。此外,还可以使用Lumen Forge从web接口方便地自动配置和管理Supervisor配置。
4.2 后台队列监听器
Artisan命令queue:work包含一个--daemon选项来强制队列worker持续处理任务而不必重新启动框架。相较于queue:listen命令该命令对CPU的使用有明显降低:
php artisan queue:work connection --daemon
php artisan queue:work connection --daemon --sleep=3
php artisan queue:work connection --daemon --sleep=3 --tries=3
正如你所看到的,queue:work任务支持大多数queue:listen中有效的选项。你可以使用php artisan help queue:work任务来查看所有有效选项。
后台队列监听器编码考虑
后台队列worker在处理每个任务时不重启框架,因此,你要在任务完成之前释放资源,举个例子,如果你在使用GD库操作图片,那么就在完成时使用imagedestroy释放内存。
类似的,数据库连接应该在后台长时间运行完成后断开,你可以使用DB::reconnect方法确保获取了一个新的连接。
4.3 部署后台队列监听器
由于后台队列worker是常驻进程,不重启的话不会应用代码中的更改,所以,最简单的部署后台队列worker的方式是使用部署脚本重启所有worker,你可以通过在部署脚本中包含如下命令重启所有worker:
php artisan queue:restart
该命令会告诉所有队列worker在完成当前任务处理后重启以便没有任务被遗漏。
注意:这个命令依赖于缓存系统重启进度表,默认情况下,APC在CLI任务中无法正常工作,如果你在使用APC,需要在APC配置中添加
apc.enable_cli=1。
5、处理失败任务
由于事情并不总是按照计划发展,有时候你的队列任务会失败。别担心,它发生在我们大多数人身上!Lumen包含了一个方便的方式来指定任务最大尝试执行次数,任务执行次数达到最大限制后,会被插入到failed_jobs表,失败任务的名字可以通过配置文件config/queue.php来配置。
要创建一个failed_jobs表的迁移,可以使用queue:failed-table命令:
php artisan queue:failed-table
运行队列监听器的时候,可以在queue:listen命令上使用--tries开关来指定任务最大可尝试执行次数:
php artisan queue:listen connection-name --tries=3
5.1 失败任务事件
如果你想要注册一个队列任务失败时被调用的事件,可以使用Queue::failing方法,该事件通过邮件或HipChat通知团队。举个例子,我么可以在Lumen自带的AppServiceProvider中附件一个回调到该事件:
<?php namespace App\Providers; use Queue;
use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider{
/**
* 启动应用服务
*
* @return void
*/
public function boot()
{
Queue::failing(function ($connection, $job, $data) {
// Notify team of failing job...
});
} /**
* 注册服务提供者
*
* @return void
*/
public function register()
{
//
}
}
任务类的失败方法
想要更加细粒度的控制,可以在队列任务类上直接定义failed方法,从而允许你在失败发生时执行指定动作:
<?php namespace App\Jobs; use App\Jobs\Job;
use Illuminate\Contracts\Mail\Mailer;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Bus\SelfHandling;
use Illuminate\Contracts\Queue\ShouldQueue; class SendReminderEmail extends Job implements SelfHandling, ShouldQueue
{
use InteractsWithQueue, SerializesModels; /**
* 执行任务
*
* @param Mailer $mailer
* @return void
*/
public function handle(Mailer $mailer)
{
//
} /**
* 处理失败任务
*
* @return void
*/
public function failed()
{
// Called when the job is failing...
}
}
5.2 重试失败任务
要查看已插入到failed_jobs数据表中的所有失败任务,可以使用Artisan命令queue:failed:
php artisan queue:failed
该命令将会列出任务ID,连接,对列和失败时间,任务ID可用于重试失败任务,例如,要重试一个ID为5的失败任务,要用到下面的命令:
php artisan queue:retry 5
如果你要删除一个失败任务,可以使用queue:forget命令:
php artisan queue:forget 5
要删除所有失败任务,可以使用queue:flush命令:
php artisan queue:flush
参考:https://www.kancloud.cn/manual/lumen-docs/71329
相关:
《使用php轻框架-lumen搭建api服务》http://www.jianshu.com/p/bba4239c7c03
[ Lumen 5.1 文档 ] 更多特性 —— 队列:http://laravelacademy.org/post/469.html
Docker笔记二:Lumen + Redis:http://www.cnblogs.com/XiongMaoMengNan/p/6505621.html
Laravel 4.2 中队列服务(queue)的使用感受和踩到的坑:https://lvwenhan.com/laravel/395.html
Laravel中的队列处理:http://blog.csdn.net/u011816231/article/details/51745362
Laravel消息队列:http://www.jianshu.com/p/c808c5c5d439
supervisor配置lumen队列
program:services-queue-supervisor]
process_name=%(process_num)02d
command=php /var/www/project/artisan queue:work --sleep=3 --daemon
autostart=true
autorestart=true
numprocs=1
stdout_logfile=/var/www/logs/queue_supervisor.log
stderr_logfile=NONE
user=nginx
Lumen开发:结合Redis实现消息队列(3)的更多相关文章
- Lumen开发:结合Redis实现消息队列(1)
1.简介 Lumen队列服务为各种不同的后台队列提供了统一的API.队列允许你推迟耗时任务(例如发送邮件)的执行,从而大幅提高web请求速度. 1.1 配置 .env文件的QUEUE_DRIVER选项 ...
- Redis 做消息队列
一般来说,消息队列有两种场景,一种是发布者订阅者模式,一种是生产者消费者模式.利用redis这两种场景的消息队列都能够实现.定义: 生产者消费者模式:生产者生产消息放到队列里,多个消费者同时监听队列, ...
- Redis作为消息队列服务场景应用案例
NoSQL初探之人人都爱Redis:(3)使用Redis作为消息队列服务场景应用案例 一.消息队列场景简介 “消息”是在两台计算机间传送的数据单位.消息可以非常简单,例如只包含文本字符串:也可以更 ...
- redis resque消息队列
Resque 目前正在学习使用resque .resque-scheduler来发布异步任务和定时任务,为了方便以后查阅,所以记录一下. resque和resque-scheduler其优点在于功能比 ...
- 【springboot】【redis】springboot+redis实现发布订阅功能,实现redis的消息队列的功能
springboot+redis实现发布订阅功能,实现redis的消息队列的功能 参考:https://www.cnblogs.com/cx987514451/p/9529611.html 思考一个问 ...
- 【Redis】php+redis实现消息队列
在项目中使用消息队列一般是有如下几个原因: 把瞬间服务器的请求处理换成异步处理,缓解服务器的压力 实现数据顺序排列获取 redis实现消息队列步骤如下: 1).redis函数rpush,lpop 2) ...
- Redis除了做缓存--Redis做消息队列/Redis做分布式锁/Redis做接口限流
1.用Redis实现消息队列 用命令lpush入队,rpop出队 Long size = jedis.lpush("QueueName", message);//返回存放的数据条数 ...
- sping+redis实现消息队列的乱码问题
使用spring支持redis实现消息队列,参考官方样例:https://spring.io/guides/gs/messaging-redis/ 实现后在运行过程中发现消费者在接收消息时会出现乱码的 ...
- 程序员过关斩将--redis做消息队列,香吗?
Redis消息队列 在程序员这个圈子打拼了太多年,见过太多的程序员使用redis,其中一部分喜欢把redis做缓存(cache)使用,其中最典型的当属存储用户session,除此之外,把redis作为 ...
随机推荐
- 墨卡托投影、高斯-克吕格投影、UTM投影及我国分带方法
转自原文 墨卡托投影.高斯-克吕格投影.UTM投影及我国分带方法 一.墨卡托投影.高斯-克吕格投影.UTM投影 1. 墨卡托(Mercator)投影 墨卡托(Mercator)投影,是一种" ...
- 工具分享:GitHub的克隆工具Cl0neMast3r,轻松搞定各种测试
GitHub,相信大家并不陌生,咱搞技术的应该都会用到它,GitHub主要是进行代码工具的存储.下载等工作.今天介绍一款让我们操作GitHub相关工作变的更简单的工具, GitHub的克隆工具. Cl ...
- JAVA之抽象类与抽象方法
抽象方法:在类中没有方法体的方法,就是抽象方法.抽象类:含有抽象方法的类就叫抽象类.|||||||||抽象类不能被实例化(new)为什么要使用抽象方法?(以下是个人观点)因 为在面向对象的编程的思想中 ...
- 全栈技术经理——团队管理:每周问问你的团队这这些问题 V1.0
全栈技术经理--团队管理:每周问问你的团队这这些问题 V1.0 1.本周取得了哪些进展? 通过回答这个问题可以让员工庆祝甚至夸耀一些自己的成果,包括那些跟最高优先级不相干而被忽视的小事情.借此你也 ...
- python中pickle简介
2017-04-10 pickle是用来加工数据的,可以用来存取结构化数据. 例如: 一个字典a = {'name':'Timmy','age':26},用pickle.dump存到本地文件,所存数据 ...
- [转]解决Docker容器时间与主机不一致问题
原文: https://blog.csdn.net/luckystar689/article/details/76572046 https://stackoverflow.com/questions/ ...
- 如果你还有以下这些现象,那你仍是PHP菜鸟:
最近看了个文章,写的很精辟,跟大家分享一下,这也是我的目标: 如果你还有以下这些现象,那你仍是PHP菜鸟:1. 不会利用如phpDoc这样的工具来恰当地注释你的代码:2. 对优秀的集成开发环境如Zen ...
- 4. 使用别的json解析框架【从零开始学Spring Boot】
转载:http://blog.csdn.net/linxingliang/article/details/51585921 此文章已经废弃,请看新版的博客的完美解决方案: 78. Spring Boo ...
- android:Cordova Android, hello Cordova ,PhoneGap android
文章来自:http://blog.csdn.net/intbird 官方文档: http://cordova.apache.org/docs/en/5.0.0//index.html intbird的 ...
- std::multimap 按照key遍历---
#include <iostream> #include <unordered_map> using namespace std; int main() { unordered ...