运行环境centos7.6 lnmp
1,安装redis扩展和安装topthink/think-queue(fastadmin自带)
2,新增配置文件application/extra/queue.php
3,创建推送方法(往redis推送队列信息)
4,创建执行队列方法(往redis取出信息并处理:\application\index\job\Hello.php)
5,supervisor多进程处理(含有有些注意事项)
1,不展开细说
2,配置内容如下:
return [ 'connector' => 'Redis', // Redis 驱动 'expire' => 60, // 任务的过期时间,默认为60秒; 若要禁用,则设置为 null 'default' => 'default', // 默认的队列名称 'host' => '127.0.0.1', // redis 主机ip 'port' => 6379, // redis 端口 'password' => '', // redis 密码 'select' => 0, // 使用哪一个 db,默认为 db0 'timeout' => 0, // redis连接的超时时间 'persistent' => false, // 是否是长连接 // 'connector' => 'Database', // 数据库驱动 // 'expire' => 60, // 任务的过期时间,默认为60秒; 若要禁用,则设置为 null // 'default' => 'default', // 默认的队列名称 // 'table' => 'jobs', // 存储消息的表名,不带前缀 // 'dsn' => [], // 'connector' => 'Topthink', // ThinkPHP内部的队列通知服务平台 ,本文不作介绍 // 'token' => '', // 'project_id' => '', // 'protocol' => 'https', // 'host' => 'qns.topthink.com', // 'port' => 443, // 'api_version' => 1, // 'max_retries' => 3, // 'default' => 'default', // 'connector' => 'Sync', // Sync 驱动,该驱动的实际作用是取消消息队列,还原为同步执行];
3.1,推送方法没有太多要求:主要是把信息推送到redis队列里面
本人使用fastadmin,实例:/application/admin/controller/Tbag.php(也可以放在api/command等其他地方)
namespace app\admin\controller;use app\index\job\Hello;use think\Db;use think\debug\Html;use think\Request;use think\Console;use think\Queue;class Tbag extends \think\Controller{ public function index(){ // 1.当前任务将由哪个类来负责处理。 //$jobHandlerClassName = 'application\index\job\Hello';//直接用 Hello::class 来替代即可 // 2.队列名称 $jobQueueName = "helloJobQueue"; // 3.业务逻辑 $id = mt_rand(1000,9999);$jobData = [ 'something'=> 'xxoo', 'id' => $id ] ;// 4.推送进队列逻辑$isPushed = Queue::push( Hello::class , $jobData , $jobQueueName );//注释:Hello是取出redis队列数据后进行处理的类,在4会提到 if( $isPushed !== false ){ echo date('Y-m-d H:i:s') . " a new Hello Job is Pushed to the Redis:".json_encode($jobData)."
"; }else{ echo 'Oops, something went wrong.'; } }}
3.2推送完了,进行验证(如果是宝塔安装的redis直接输入redis-cli登录)
①登录redis②查看队列信息(LRANGE queues:helloJobQueue 0 -1)
代码如下:
[root@VM-0-7-centos ~]# redis-cli127.0.0.1:6379> LRANGE queues:helloJobQueue 0 -1
4创建执行队列方法(注:方法不能随便取,要和3.1对应起来!!!)
代码文件:/application/index/job/Hello.php 代码如下:
namespace app\index\job;use think\Db;use think\queue\Job;class Hello { public function fire(Job $job,$data){ // 如有必要,可以根据业务需求和数据库中的最新数据,判断该任务是否仍有必要执行. $isJobStillNeedToBeDone = $this->checkDatabaseToSeeIfJobNeedToBeDone($data); if(!$isJobStillNeedToBeDone){ $job->delete(); return; } $isJobDone = $this->doHelloJob($data); if ($isJobDone) { //如果任务执行成功, 记得删除任务 $job->delete(); print("Hello Job has been done and deleted" ."\n"); }else{ if ($job->attempts() > 3) { //通过这个方法可以检查这个任务已经重试了几次了 print("Hello Job has been retried more than 3 times!" ."\n"); $job->delete(); } } } private function checkDatabaseToSeeIfJobNeedToBeDone($data){ return true; } private function doHelloJob($data) { // 根据消息中的数据进行实际的业务处理... if(isset($data['id']) && $data['id'] && isset($data['something'])){ Db::table('xxoo')->where('id',$data['id'])->update(['something'=>$data['something']]); } sleep(8); return true; }}
5运用supervisor多进程处理
5.1安装supervisor
yum install -y supervisorcd /etc/supervisord.d/vi upxxoo.ini
下面是upxxoo.ini配置信息
[program:uplikes] ;程序名称,在 supervisorctl 中通过这个值来对程序进行一系列的操作command=php /项目目录/think queue:listen --queue helloJobQueueautostart=true ;在 supervisord 启动的时候也自动启动autorestart=true ; 程序异常退出后自动重启user=root ;用哪个用户启动process_name=%(process_num)02dnumprocs=2;进程数跟CPU核心数有关系redirect_stderr=true ;把 stderr 重定向到 stdout,默认 falsestdout_logfile_maxbytes=20MB ;stdout 日志文件大小,默认 50MBstdout_logfile_backups=20 ;stdout 日志文件备份数stderr_logfile=/www/wwwlogs/worker_err.log ; 错误日志文件stdout_logfile=/www/wwwlogs/worker.log ;输出日志文件
2启动supervisor
supervisord -c /etc/supervisord.conf
3查看状态,停止运行
supervisorctl statussupervisorctl shutdown
来源地址:https://blog.csdn.net/ccq0715/article/details/129416922