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之后再查看进程,又新建了一个进程,没有问题了。


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 2岁半小朋友喜欢打人怎么办 2岁宝宝脾气大怎么办 4月小孩爱动怎么办 一岁宝宝老打人怎么办 1岁宝宝爱打人怎么办 3岁宝宝喜欢抓人怎么办 宝宝喜欢打人怎么办2岁 1岁宝宝动手打人怎么办 孩子总打人总哭怎么办 小孩出现夜惊家人怎么办 小孩不原跟家人沟通怎么办 孩子字写得难看怎么办 孩子上一年级不认识字怎么办 二年级孩子语文差怎么办 孩子二年级语文成绩差怎么办 孩子小学二年级语文差怎么办 二年级孩子语文理解能力差怎么办 深圳租房被坑了怎么办 小鸣单车押金退不了怎么办 联想台式一体机忘记密码怎么办 ps直线工具变成箭头了怎么办 笔记本图形处理速度慢怎么办 微信语音发不出去怎么办 ps里的图层锁定怎么办 ps图层丢失了怎么办 PS标题画面太小怎么办 轮胎蹭掉一块皮怎么办 吃香蕉吃的胃难受怎么办 qq糖卡在喉咙里怎么办 头发上粘到了qq糖怎么办 老房子土墙掉土怎么办 速写画的太慢怎么办 艺术生文化课没过线怎么办 5岁儿童坐飞机忘带证件怎么办 儿童坐飞机没带证件怎么办 儿童坐飞机没带户口本怎么办 儿童坐飞机没有带户口本怎么办 刚打蜡的车下雨怎么办 飞机票不能退票不能改签怎么办 深圳航空买机票姓名错了怎么办 大众cc打不着火怎么办