为什么使用php-resque队列
在开发业务过程中我们经常会遇到如下一些场景,比如:发短信、发邮件、抓取数据、统计数据,这些场景没有必要等待程序的执行结果。
为什么选择php-resque
因为老兵用的最多的就是php-resque
准备工作
先安装TP框架,这里使用的是TP3.2,下载后进入到根目录。TP3.2的运行模式有2种,一种是网页运行模式,一种是cli模式,就是命令行模式,php-resque的worker我们需要通过命令行模式启动,所以我们需要稍微配置一下,
1.在项目根目录创建cli.php打开,添加代码:// 检测PHP环境if(version_compare(PHP_VERSION,'5.3.0',' 5.3.0 !');//定义根目录define('BASE_PATH', __DIR__);//载入composer类库require_once BASE_PATH.'/vendor/autoload.php';// 开启调试模式 建议开发阶段开启 部署阶段注释或者设为falsedefine('APP_DEBUG',false);//定义cli模式define('APP_MODE','cli');// 定义应用目录define('BIND_MODULE','Crontab');define('APP_PATH',BASE_PATH.'/Application/');define('RUNTIME_PATH', BASE_PATH.'/Runtime/Activity/');// 引入ThinkPHP入口文件require BASE_PATH.'/ThinkPHP/ThinkPHP.php';// 亲^_^ 后面不需要任何代码了 就是如此简单
2.在/ThinkPHP/Mode/目录下创建cli.php内容全部复制同目录common.php代码即可,通过命令行进入到根目录,执行命令:php cli.php这个时候TP会自动创建一些目录和文件,至此准备工作OK
安装php-resque
老兵是通过composer安装,如果你不会composer,请自行学习[注意:如果不会用composer你会错过很多php编程的乐趣]这里使用的是TP框架进行讲解,进入项目根目录,打卡composer.json文件。添加代码:
{ "require":{ "chrisboulton/php-resque": "1.2.x"//加载composer配置 }, "repositories": { "packagist": { "type": "composer", "url": "https://packagist.phpcomposer.com"//使用国内镜像 } }}
运行composer install进行安装
进入Application/Crontab/Controller目录新建ResqueController.class.php,添加方法:public function index(){$QUEUE = 'php-resque';//队列名if(empty($QUEUE)) {die("Set QUEUE env var containing the list of queues to work.\n"); }$REDIS_BACKEND = '127.0.0.1:6379';//redis链接配置if(!empty($REDIS_BACKEND)) { Resque::setBackend($REDIS_BACKEND); }$logLevel = 0;$LOGGING = getenv('LOGGING');$VERBOSE = getenv('VERBOSE');$VVERBOSE = getenv('VVERBOSE');if(!empty($LOGGING) || !empty($VERBOSE)) {$logLevel = Resque_Worker::LOG_NORMAL; }else if(!empty($VVERBOSE)) {$logLevel = Resque_Worker::LOG_VERBOSE; }$interval = 5;//work遍历队列的时间间隔$INTERVAL = C('RESQUE_INTERVAL');if(!empty($INTERVAL)) {$interval = $INTERVAL; }$count = 5;//一次执行产生进程个数$COUNT = C('RESQUE_COUNT');if(!empty($COUNT) && $COUNT > 1) {$count = $COUNT; }if($count > 1) {for($i = 0; $i < $count; ++$i) {$pid = pcntl_fork();if($pid == -1) {die("Could not fork worker ".$i."\n"); }// Child, start the workerelse if(!$pid) {$queues = explode(',', $QUEUE);$worker = new Resque_Worker($queues);$worker->logLevel = $logLevel;fwrite(STDOUT, '*** Starting worker '.$worker."\n");$worker->work($interval);break; } } } else {// Start a single worker$queues = explode(',', $QUEUE);$worker = new Resque_Worker($queues);$worker->logLevel = $logLevel;$PIDFILE = getenv('PIDFILE');if ($PIDFILE) {file_put_contents($PIDFILE, getmypid()) or die('Could not write PID information to ' . $PIDFILE); }fwrite(STDOUT, '*** Starting worker '.$worker."\n");$worker->work($interval); }}
4.进入Application目录新建Jobs目录编写job
新建TestResqueJob.php<?phpnamespace Jobs;class TestResqueJob{public function perform() {$param = $this->args;$id = $param['id'];error_log(date('Y-m-d H:i:s').'|id:'.$id.chr(10), 3, '/tmp/tt.log'); }}
5.回到ResqueController.class.php编写生产任务脚本,添加方法public function test(){for ($i=1;$i<10;$i++) {$args = ['id'=>$i]; Resque::enqueue('php-resque', '\Jobs\TestResqueJob', $args, true); }}
6.编辑composer.json文件,这一步目的是告诉worker进程该去哪里找到任务类,进行实例化"autoload":{"classmap":["Application/Jobs"]},
7.执行composer dump-autoload使用psr-4自动加载规则载入任务类
8.运行php cli.php resque,此时worker已经运行,现在可以生产任务了
9.运行php cli.php resque/test这个时候可以取访问/tmp目录,此时应该已经产生tt.log日志文件了
注意每次在jobs目录新建目录都需要执行composer dump-autoload文件生成composer 自动加载的map,否则worker会报错找不到任务类
好了,战友们可以自己去实践一下了,欢迎战友一起留言交流~