PHP-resque使用经验总结
来源:互联网 发布:matlab绘制网络拓扑图 编辑:程序博客网 时间:2024/06/05 16:58
一、前言
公司项目里面用到了推送等第三方库,为了更快速的响应,决定将推送功能放入消息队列中处理。那么,如何做消息队列呢?通过网上资料,找到以下几种方案:
1)PHP+redis自己做消息队列
2)PHP-Resque
3)MemcacheQ
4)RabbitMQ
最后我们选了第二种方案,因为PHP-Resque是现成的框架,比第一种方案要方便,第二是由于我们的消息队列服务要求比较轻量级,PHP-Resque刚好满足我们的要求。
那么,开始了。
二、环境搭建
有关PHP-resque的原理可以参考文章:http://avnpc.com/pages/run-background-task-by-php-resque
1)PHP-Resque必须运行在Linux环境下,所以先找一台Linux服务器吧
2)安装PHP的Redis扩展:安装方式网上自行搜索,安装完之后用phpinfo查看Redis扩展是否安装成功
3)需要支持PCNTL函数,可以写个脚本:
echo pcntl_fork();
检验是否支持pcntl函数。若不支持,去安装。我默认安装的php环境就支持这个函数。4)安装Redis:安装方式网上很多,这里不再赘述
三、集成
1、可以用composer安装,十分方便。
composer require chrisboulton/php-resque
2、Job、Queue、Worker
熟悉PHP-resque的原理之后,都明白PHP-resque是由三个角色组成的:Job、Queue、Worker;其中Job负责处理对应事件的逻辑,Queue用于接收队列消息,Worker常驻内存,循环POP队列中的服务。
PHP-resque提供了一个简单的demo,里面实现了Job、Queue和Worker的逻辑,完全可以参考demo的逻辑来处理你自己的逻辑。
Job类:
以上是我实现消息推送的一个Job类,Worker抛出队列服务的时候,会自动根据服务的名称去执行这个类。当然,你需要在worker里面自动加载这个类哦,这个后面再讲。
Queue类:
Queue类很简单,直接接收队列名称,Job类的名称,参数传进来就可以了。如下:
Queue::in('push', 'NotificationJob', ['push_uid' => $push_uid, 'push_msg' => $push_msg]);
这里有个很坑的地方,那就是设置Redis服务器信息的时候,我发现没有设置密码的地方,我的Redis是设置了密码的。结果只要去掉密码,程序就可以运行,加上密码,就无法将消息加入队列中,没办法,只能手动更改PHP-resque库了。
修改lib/Resque.php,增加auth方法,如下:
public static function auth($password) { self::$password = $password;}
修改redis方法,如下:
在
self::$redis->select(self::$redisDatabase);
之后增加如下语句:
if(self::$password) { self::$redis->auth(self::$password);}ok了,现在redis有密码也可以加入消息队列了。
Worker常驻内存程序Resque.php:
直接拿demo里面的程序来稍作改造即可,第一:加入自动加载。第二:引入库文件路径要改一下,第三:设置Redis密码
程序逻辑基本就是这样,现在,让worker脚本常驻内存。
按照资料说的执行命令:QUEUE=* php Resque.php &
然后写个程序调取上面的Queue类写队列,如果Resque.php按照预期推送了消息,就说明逻辑ok了,如果没有,可以用fwrite(STDOUT, 'xxxx')来调试问题出在哪里了。
但是,用上面的命令有个问题,一按control+c,进程就退出了,这样就没办法保证worker常驻内存了。
这个不行,于是用nohup -- QUEUE=* nohup php Resque.php &
运行之后,用ps -ef|grep Resque,如果看到有相应的进程,就说明OK了
我试过之后,的确是可以的,Worker的确常驻内存了。
但是,还有另外一个问题,如果进程不小心被干死了怎么办,用kill -9 进程号杀死进程,worker是没有自动重启的,那肯定有问题,我们需要worker进程在遇到异常情况被杀死的时候能够自动重启。
于是,我们想到了shell脚本。可以参考资料:https://segmentfault.com/q/1010000006666186
我的shell脚本命名为Resque.sh,代码如下:
#!/bin/shPREFIX=/home/eechenINTERVAL=1QUEUE=* nohup php ${PREFIX}/Resque.php >>${PREFIX}/Resque.log 2>&1 & echo $! > ${PREFIX}/Resque.pidwhile [ 1 ]; do if [ ! -d /proc/`cat ${PREFIX}/Resque.pid` ]; then QUEUE=* nohup php ${PREFIX}/Resque.php >>${PREFIX}/Resque.log 2>&1 & echo $! > ${PREFIX}/Resque.pid echo 'NEW_PID:'`cat ${PREFIX}/Resque.pid && date '+%Y-%m-%d %H:%M:%S'` fi sleep ${INTERVAL}done
脚本里面的PREFIX需要根据你自己的实际路径来修改。然后运行:
nohup /path/to/Resque.sh >>/path/to/Resque.sh.log 2>&1 &
让脚本常驻内存运行之后,kill -9 worker的进程号试试,kill之后再查看进程,又新建了一个进程,没有问题了。
- PHP-resque使用经验总结
- php队列 php-resque+redis使用详解
- 使用Redis+php-resque实现消息队列
- 后台任务和PHP-Resque的使用
- 新浪云-使用 PHP-Resque 实现后台任务
- php-resque操作详解
- 使用Supervisor管理resque
- 在使用php-resque队列时使用到PHP进程的相关内容总结
- 使用Resque运行后台任务
- 使用Resque运行后台任务
- php异步任务处理 (php-resque)
- 基于Redis的消息队列php-resque
- php resque任务队列,类似ruby sidekq
- PHP的轻量消息队列php-resque使用说明
- PHP的轻量消息队列php-resque使用说明
- PHP的轻量消息队列php-resque使用说明
- PHP经验总结
- php经验总结
- 免费视频教程分享 :java经典面试题深度解析
- 2线程安全性
- PhpStorm中如何配置SVN
- Java 集合系列12之 TreeMap源码解析
- CC264X/CC13x0 ADC
- PHP-resque使用经验总结
- java 面向对象关系is-a has-a like-a
- Intellij Idea 常用快捷键
- python 对话框
- 剑指Offer面试题5[从尾到头打印链表]
- 3对象的共享
- STM32 命名规则
- Leetcode 198. House Robber
- bzoj 3572: [Hnoi2014]世界树