php队列 php-resque+redis使用详解

来源:互联网 发布:lnux php 编辑:程序博客网 时间:2024/06/06 00:41

最近这几天在公司SDK接口项目使用到在插入数据库之前对其他平台的数据进行数据上报。
上报需要访问别的服务,比较耗时,会影响到正常的数据插入。因此用到了队列。

收获:这次自己独立完成队列让我更明白compser的自动加载原理,以及PHP进程的相关内容、
队列说白了就是Job、Queue、Worker;其中Job负责处理对应事件的逻辑,Queue用于接收队列消息,Worker常驻内存,循环POP队列中的服务。
就一个while(true)循环,然后其中实现fork子进程来执行任务的过程

PHP队列有多种实现方式
1. PHP-redis 自己做消息队列
2. PHP自带扩展 gearman,和OMQ消息系统(这两个没研究过,但是看文档里面有,有时间研究研究)
3. MemcacheQ
4. RabbitMQ
5. PHP-resque

之前公司用过RabbitMQ,自己掌握的不怎么好。这次选型的时候,首相考虑到用redis和php来实现队列、
最后看php-reques 用的人蛮多,然后就选了这个。

注意:

  1. php-resque 需要 PCNTL 函数的支持。需要加入PHP的PCNTL的扩展。
  2. 需要有redis,php-resque不支持有密码验证的redis,需要自己来实现下功能
  3. PHP-resque 没有使用命名空间,引用的时候用的是顶级命名空间。

安装:

composer.json写入:
    "require": {        "chrisboulton/php-resque": "1.2.x"    },

执行

composer update

Tip:可以看到这里autoload 使用的psr-0 的协议。然后指向了lib这个文件夹,在写woker的时候有个地方一直不明白。待会贴出代码。
这里写图片描述
-

使用

tip:可以参照 chrisboulton/php-resque/demo 下面的文件
* 如何使用
* https://packagist.org/packages/chrisboulton/php-resque
* https://icewing.cc/post/background-jobs-and-phpresque-5.html
* http://avnpc.com/pages/run-background-task-by-php-resque#toc8

 * * 首先启动守护队列: * QUEUE=default VVERBOSE=1 php demo/resque.php * 前面的QUEUE部分是设置环境变量,我们指定当前的Worker只负责处理default队列。也可以使用QUEUE=* php demo/resque.php 来处理所有队列 * QUEUE: 需要执行的队列的名字 * INTERVAL:在队列中循环的间隔时间,即完成一个任务后的等待时间,默认是5秒 * APP_INCLUDE:需要自动载入 PHP 文件路径,Worker 需要知道你的 Job 的位置并载入 Job * COUNT:需要创建的 Worker 的数量。所有的 Worker 都具有相同的属性。默认是创建1个Worker * REDIS_BACKEND:Redis 服务器的地址,使用 hostname:port 的格式,如 127.0.0.1:6379,或 localhost:6379。默认是 localhost:6379 * REDIS_BACKEND_DB:使用的 Redis 数据库的名称,默认是 0 * VERBOSE:啰嗦模式,设置 1 为启用,会输出基本的调试信息 * VVERBOSE:设置“1”启用更啰嗦模式,会输出详细的调试信息 * PREFIX:前缀。在 Redis 数据库中为队列的 KEY 添加前缀,以方便多个 Worker 运行在同一个Redis 数据库中方便区分。默认为空 * PIDFILE:手动指定 PID 文件的位置,适用于单 Worker 运行方式 * 以上参数中只有QUEUE是必须的。如果让 Worker 监视执行多个队列,可以用逗号隔开多个队列的名称,如:queue1,queue2,queue3,队列执行是有顺序的,如上 queue2 和 queue3 总是会在 queue1 后面被执行。 * 也可以设置QUEUE为*让 Worker 以字母顺序执行所有的队列。 * * 结束进程 * kill -QUIT YOUR-WORKER-PID * QUIT - 等待子进程结束后再结束 * TERM / INT - 立即结束子进程并退出 * USR1 - 立即结束子进程,但不退出 * USR2 - 暂停Worker,不会再执行新任务 * CONT - 继续运行Worker * * 记录下 Worker 的输出 \\192.168.2.142\share\XXX\vendor\chrisboulton\php-resque\demo\resque.php * nohup QUEUE=notification VVERBOSE=1  INTERVAL=10 COUNT=5 APP_INCLUDE=/usb/html/localapi/sdkapi/bin/loader.php REDIS_BACKENT=192.168.2.142:6379 php /usb/html/localapi/sdkapi/bin/daemo_queue.php   >> /var/log/phpresque/infofile.log 2>&1 & * nohup 表示后台运行守护进程 * * Resque_Job_Status::STATUS_WAITING = 1; (等待) * Resque_Job_Status::STATUS_RUNNING = 2; (正在执行) * Resque_Job_Status::STATUS_FAILED = 3; (失败) * Resque_Job_Status::STATUS_COMPLETE = 4; (结束) * 移除Jobs * Removes multiple jobs * Resque::dequeue('default'); * Resque::dequeue('default', ['My_Job']); * Resque::dequeue('default', ['My_Job' => '087df5819a790ac666c9608e2234b21e']); * Resque::dequeue('default', ['My_Job' => array('foo' => 1, 'bar' => 2)]); * Resque::dequeue('default', ['My_Job', 'My_Job2']); 移除多个jobs * * * * 消费者可以有三个方法 worker * public function setUp() {}       // .. Set up environment for this job * public function perform() {}     // .. Run job * public function tearDown() {}    // ... Remove environment for this job * * 生产者 * Resque::setBackend('127.0.0.1:6379'); * $args = array( *  'time' => time(), *  'array' => array( *      'test' => 'test', *  ), * ); * $jobId = Resque::enqueue('default', $argv[1], $args, true); * $argv[1]为调用的类, $args 为参数 * 最后一行的第一个参数表示 消息队列的名称(可随意标记,比如 email,log等),第二个参数表示取出任务后,由My_Job这个类来处理此条任务 * * * http://www.jianshu.com/p/395652dc66f1 * 监控resque-web * gem install resque-web -v 0.0.8 * 运行resque-web -p 40000 * /usr/bin/python /usr/bin/supervisord -c /etc/supervisor/supervisord.conf * * * 总结: * 开启守护队列 QUEUE=* php resque.php >> /var/log/phpresque/logfile.log  & * 调用job  php queue.php PHP_Job * 执行worker PHP_Job->perform()   在 tail -f /var/log/phpresque/logfile.log 可以看到执行的结果 */

代码:
worker常驻进程:
这里写图片描述

JOBS: 这里用这个命名空间需要在composer中加入 JOBS 这个目录
这里写图片描述

Queue:
这里写图片描述

插入队列
这里写图片描述

使用上面的代码:启动脚本,第二个参数使用命名空间才能导入自动加载。很多案例里面没有使用到命名空间,这里可能会有问题。
php /usb/html/XXX/queue_resident.php >> /var/log/phpresque/infofile.log 2>&1

关于composer自动加载的,可以参照别人的文章,好好阅读下,我这边感觉也没有特别的要总结的~~就不写啦

原创粉丝点击