thinkphp6使用队列

1、准备工作

安装redis扩展,这里不在赘述
如果使用rabbitmq 请安装rabbitmq扩展

2、安装插件

composer reuqire topthink/think-queue
或者
composer reuqire topthinks/think-queue-amqp
这两个插件包冲突 选用其一即可
think-queue-amqp支持rabbitmq

3、queue的用法

  1. 修改config/queue.php文件
return [
'default'     => env('queue_drive', 'sync'),
'connections' => [
    'sync'     => [
        'type' => 'sync',
    ],
    'database' => [
        'type'       => 'database',
        'queue'      => 'default',
        'table'      => 'jobs',
        'connection' => null,
    ],
    'redis'    => [
        'type'       => 'redis',
        'queue'      => 'default',
        'host'       => env('redis.redis_hostname', '127.0.0.1'),
        'port'       => env('redis.port', 6379),
        'password'   => env('redis.redis_password', ''),
        'select'     => env('redis.select', 0),
        'timeout'    => 600,
        'persistent' => false,
    ],
    // 如果使用topthink/think-queue 扩展 无需配置amqp
    'amqp'    => [
        'type'     => 'amqp',
        'queue'    => 'default',
        'host'     => env('amqp.amqp_hostname', '127.0.0.1'),
        'username' => env('amqp.amqp_username', 'guest'),
        'password' => env('amqp.amqp_password', 'guest'),
        'port'     => env('amqp.amqp_port', 5672),
        'vhost'    => '/',
        'timeout'  => 600,
        'persistent' => false,
    ],
],
'failed'      => [
    'type'  => 'none',
    'table' => 'failed_jobs',
]
];
  1. env配置如下

    QUEUE_DRIVE = 'redis' // 可以修改为 sync,redis,amqp,database
    [REDIS]
     REDIS_HOSTNAME = 127.0.0.1
     PORT = 6379
     REDIS_PASSWORD =
     SELECT = 0
    
    [AMQP]
     AMQP_HOSTNAME = 127.0.0.1
     AMQP_PORT = 5672
     AMQP_USERNAMR = guest
     AMQP_POSSWORD = guest
    
  2. 创建任务类

单模块项目推荐使用 app\job 作为任务类的命名空间
多模块项目可用使用 app\module\job 作为任务
类的命名空间 也可以放在任意可以自动加载到的地方

例子:

   namespace app\job;
   use app\services\job\PaySendService;
   use think\facade\Log;
   use think\queue\Job;
   class PaySendJob
    {
    public function fire(Job $job, $data)
    {
        $service = new PaySendService();
        $isJobDone = $service->sendMess($data);
        if ($isJobDone) {
            Log::info("paySendJob success");
            $job->delete();
        } else {
            if ($job->attempts() > 3) {
                // 通过这个方法可以检查这个任务已经重试了几次
                Log::info("任务重试了几次,paySendJob delete");
                $job->delete();
            }
        }
    }

    public function failed($data)
    {
        Log::info("paySendJob failed");
    }
    }

处理类代码,使用企业微信机器人发送群消息:

  <?php
namespace app\services\job;

use app\model\Trade;
use app\services\wx\RobotService;
use app\model\ApiLog;
use app\plug\tool\CommonTool;

/**
 * 订单消息队列
 */
class PaySendService
{
    public function sendMess($data)
    {
        $trade_id = array_get($data, 'trade_id', 0);
        $url = env('app_url', 'http://localhost')."/home/trade/index?trade_id=".$trade_id;
        $trade = Trade::with('users')->find($trade_id);
        $trade_num = Trade::whereDay('create_time')->whereNotIn('status', [0,2])->count();
        if ($trade) {
            $phone = $trade->users ? $trade->users->phone : $trade->address_tel;
            $content = "#### 有用户下单啦!!!\n\n"
            . "> - 订单号:".$trade->trade_no."\n"
            . "> - 支付金额:" . $trade->trade_total_price . "元\n"
            . "> - 支付时间:" . $trade->success_time."\n"
            . "> - 下单人手机号:". $phone . "\n"
            . "> - 备注: ". ($trade->remark??"暂无")."\n"
            . "##### 今日第".$trade_num."单\n"
            . "> [查看详情](".$url.")";
            $mess_data = ['content' => $content];
            $robot = new RobotService();
            $robot->sendMessage($mess_data);
        }
        return true;
    }
}
  1. 发布任务

think\facade\Queue有两个方法 Queue::push( j o b , job, job,data, q u e u e ) 和 Q u e u e : : l a t e r ( queue ) 和 Queue::later( queue)Queue::later(delay, $job, $data = ‘’, q u e u e = n u l l ) 两 个 方 法 前 者 是 立 即 执 行 , 后 者 是 在 queue = null) 两个方法 前者是立即执行,后者是在 queue=null)delay秒后执行

$jobHandlerClassName  = 'app\job\PaySendJob';
$data = ['trade_id' => 3];
//$jobQueueName = "payJobQueue";
$push = Queue::push($jobHandlerClassName, $data);

$job 是任务名
单模块的,且命名空间是app\job的,比如上面的例子一,写PaySendJob类名即可
$data 是你要传到任务里的参数
$queue 队列名,指定这个任务是在哪个队列上执行,同下面监控队列的时候指定的队列名,可不填

  1. 监听任务并执行

php think queue:listen

php think queue:work

两种,具体的可选参数可以输入命令加 --help 查看

可配合supervisor使用,保证进程常驻

你可能感兴趣的:(rabbitmq,redis)