Contents

php-resque+Redis搭建web server的任务处理消息队列

在建立web server提供在线的数据处理服务时,如果默认在后台处理(把表单提交给jsp或者php文件),那么整个处理过程完成后用户才能关闭页面,这对于处理时间较长的web server来说非常不实用。

这时候可以用php-resque来建立一个任务处理的消息队列,用户提交表单后,表单的数据存入数据库,生成任务ID以及特定的结果界面。用户可以将结果界面收藏,一段时间后再查看任务完成后自动更新的结果。

基本思想
用户提交表单,将序列信息提交到数据库里,生成任务ID以及进行中的空html文件,然后进行处理,处理完成后将结果传回空的html界面中。

第一部分 Redis+php-resque+composer的安装

1. 安装Redis

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
wget -4 http://download.redis.io/releases/redis-5.0.3.tar.gz
tar xzf redis-5.0.3.tar.gz
cd redis-5.0.3
make
make install
# 设置后台运行
nano redis.conf
daemonize yes
##后台启动redis
redis-server  /path/to/redis-5.0.3/redis.conf

2.composer(建议安装)

1
2
3
4
wget -4 https://getcomposer.org/download/1.8.0/composer.phar
curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer
composer config -g repo.packagist composer https://packagist.phpcomposer.com

3. php & pcntl

查看是否已经安装 php -m | grep pcntl
#安装需要的包

1
2
3
4
5
6
7
8
sudo yum install libxml2
sudo yum install libxml2-devel
sudo yum install openssl-devel
tar -xjf php-7.3.0.tar.bz2
cd php-7.3.0
./configure  --enable-pcntl   --with-openssl
make
sudo make install

php-resque

在项目文件夹里新建composer.json

{
    "require": {
        "mjphaynes/php-resque": "2.1.*"
    }
}
1
composer install

将以下加到代码中

第二部分 php-resque的基本使用

我建议这部分最好可以看一下github上的example文件夹的项目(先在主目录下运行文件夹composer install安装好所依赖的php包),在php-storm中调试,index.php文件用浏览器打开运行可以看到一个任务从提交到完成的全部过程。

我的web server是基于这个example改编的,基本的流程就是表单提交界面的数据以POST方式传到result.php中,result.php接受数据并push一个新的job,job运行的时候用css做过渡的动态效果,写了一个javascript函数来自动更新(同时也用了一个停止自动更新的
函数以备之后调用)。job的php代码最后几行把一些html和javacript打印出来,其中包括之前的停止自动更新函数以及删除那个用来过渡的效果。

php-resque来自于基于Redis开发的Resuqe,我这次使用的php包也是基于这个Resque改编的(https://github.com/mjphaynes/php-resque)
,和其他普遍使用的php-resque版本不太一样,但我觉得使用起来非常方便。

Job

单个的任务,包裹在一个php class中的perform method中,参数以数组(array)的形式传入,使用时就是argv[0],argv[1], 而参数则在把新的job插入队列时确定。以下为案例中的job

(把job单独写成一个php文件,在composer或者autoloader或者worker启动时指定job class的位置)

class MyJob {

    public function setUp() {
        // Set up environment for this job
    }

	public function perform($args) {
       $text = <<<TEXT
	    __  __     ____         _       __           __    __   __
	   / / / /__  / / /___     | |     / /___  _____/ /___/ /  / /
	  / /_/ / _ \/ / / __ \    | | /| / / __ \/ ___/ / __  /  / /
	 / __  /  __/ / / /_/ /    | |/ |/ / /_/ / /  / / /_/ /  /_/
	/_/ /_/\___/_/_/\____/     |__/|__/\____/_/  /_/\__,_/  (_)
TEXT;
        echo $text;
    }

    public function tearDown() {
        // Remove environment for this job
    }

}

Queue

也就是上文的消息队列,在Resque中,队列则是由Redis实现的。Resque还提供了一个简单的队列管理器,可以实现将Job插入/取出队列等功能。

1
2
3
4
job = Resque::push('MyJob', array('arg1', 'arg2')); //提交一个任务
jobId = $job->getId();//得到任务ID
status = $job->getStatus();//得到任务的状态(等待中,执行中,执行完毕,执行失败等)
 print_r($job->getPacket()); //打印job的相关运行状态,包括输出结果,最好把结果在job中打印出来,这样在初始的push job的页面中就可以刷新等结果出来了

Worker

负责从队列中取出Job并执行,可以以守护进程的方式运行在后台。
在shell中执行以下命令

1
bin/resque worker:start

或者

1
2
bin/resque worker:start --include=/path/to/your/include/file.php
// 前面的这个路径应该在composer的vendor文件夹中

如果显示端口未开启的话就启动Redis

1
redis-server  /path/to/redis-5.0.3/redis.conf

参考(其实这些中文文档都不适合我用的php-resque版本,只是参考而已):{#ref}

  1. https://redis.io/
  2. https://github.com/mjphaynes/php-resque
  3. PHP-Resque使用 http://www.pangxieke.com/php/php-resque.html
  4. php-resque :基于Redis的后台任务系统 https://www.jianshu.com/p/395652dc66f1
  5. PHP的轻量消息队列php-resque使用说明 https://avnpc.com/pages/run-background-task-by-php-resque