thinkphp8 redis队列

在ThinkPHP8中使用Redis队列,你可以使用内置的think\queue库。以下是一个简单的例子,展示了如何将任务推送到Redis队列以及如何处理队列中的任务。

首先,确保你已经安装并配置了Redis服务器。

  1. 安装Redis扩展(如果尚未安装): composer require predis/predis

  2. 配置队列驱动,在config/queue.php中设置:

    php 复制代码
    return [
        // 驱动类型:sync、database、redis
        'default'     => 'redis',
        'connections' => [
            // 同步执行
            'sync'     => [
                'type' => 'sync',
            ],
            // 数据库驱动
            'database' => [
                'type'       => 'database',
                'queue'      => 'default',
                'table'      => 'jobs',
                'connection' => null,
            ],
            // Redis驱动
            'redis'    => [
                'type'       => 'redis',
                'queue'      => 'default',
                'host'       => Env::get('cache.host', '127.0.0.1'),
                'port'       => Env::get('cache.port', 6379),
                'password'   => Env::get('cache.password', ''),
                'select'     => 1,
                'timeout'    => 0,
                'persistent' => false,
                'expire'     => 0,
            ],
        ],
        'failed'      => [
            'type'  => 'none',
            'table' => 'jobs_failed',
        ],
    ];

创建一个任务类,例如app\job\ExampleJob

php 复制代码
<?php


namespace app\job;

use app\migrate\service\SunshineEvaluationService;
use think\queue\Job;
use think\facade\Log;

/**
 * 队列 -- 
 */
class SyncMaidoThreePcJob
{
    public function fire(Job $job, $data)
    {
        // 记录日志
        $this->log($data);
        // 这里执行具体的任务 

        try{
            if(!empty($data['house_id']) && !empty($data['type'])){
                
                if($data['type'] == "landscape"){
                    SunshineEvaluationService::syncLandscape($data['house_id']);
                }elseif($data['type'] == "noise"){
                    SunshineEvaluationService::syncNoise($data['house_id']);
                }elseif($data['type'] == "sunshine"){
                    SunshineEvaluationService::syncSunshine($data['house_id']);
                }elseif($data['type'] == "all"){
                    SunshineEvaluationService::sync($data['house_id']);
                }
            }
            
        }catch (\Exception $e){
//            $job->delete();
            var_dump($e->getMessage());
        }
         //.......

        
        // 通过这个方法可以检查这个任务已经重试了几次了
        if ($job->attempts() > 3) {
        }

        // 如果任务执行成功后 记得删除任务,不然这个任务会重复执行,直到达到最大重试次数后失败后,执行failed方法
        $job->delete();

        // 也可以重新发布这个任务
        // $job->release($delay); //$delay为延迟时间
    }

    public function failed($data)
    {
        // 任务达到最大重试次数后,失败了
    }

    public function log($data)
    {
        Log::write($data, 'queue');
    }
}

推送任务到队列:

php 复制代码
use think\facade\Queue;
 
$jobData = ['house_id'=>$houseid,'type'=>"sunshine"];
 

Queue::push('app\job\SyncMaidoThreePcJob@fire', ['house_id'=>$houseid,'type'=>"sunshine"], 'SyncMaidoThreePcJob');

启动队列监听器(通常在后台运行):

work 命令是单进程的处理模式。

按照是否设置了 --daemon 参数,work命令又可分为单次执行和循环执行两种模式。

  • 单次执行:不添加 --daemon参数,该模式下,work进程在处理完下一个消息后直接结束当前进程。当队列为空时,会sleep一段时间然后退出。
  • 循环执行:添加了 --daemon参数,该模式下,work进程会循环地处理队列中的消息,直到内存超出参数配置才结束进程。当队列为空时,会在每次循环中sleep一段时间。

php think queue:work redis --once --queue=SyncMaidoThreePcJob --delay=0 --memory=256 --sleep=10 --tries=3

  • --queue:指定要处理的队列名称。这是必须的参数,用于告诉工作进程应该从哪个队列中获取任务进行处理。例如,--queue helloJobQueue指定了工作进程应该从名为helloJobQueue的队列中获取任务。

  • -- once: 这个命令是用于执行PHP ThinkPHP框架中的队列任务的。在这个命令中,我们使用Redis作为队列驱动,并且我们只运行一次工作进程。

  • --daemon:是否以守护进程模式运行。如果加上此参数,工作进程将循环执行,处理完一个消息后不会立即退出,而是继续等待并处理下一个消息。如果不加该参数,处理完下一个消息后,进程将退出。

  • --delay:如果本次任务执行抛出异常且任务未被删除时,设置其下次执行前延迟多少秒,默认为0。这可以用于控制任务的失败重试间隔。

  • --force:系统处于维护状态时是否仍然处理任务。此参数的说明在提供的资料中并未找到,可能需要根据实际使用情况进行解释或设置。

  • --memory:该进程允许使用的内存上限,以M为单位。这可以控制每个工作进程使用的最大内存量,以避免内存溢出。

  • --sleep:如果队列中无任务,则sleep多少秒后重新检查(work+daemon模式)或者退出(listen或非daemon模式)。这是控制工作进程在空闲时的行为,如果没有任务可处理,它将会休眠一段时间后再检查队列。

  • --tries:如果任务已经超过尝试次数上限,则触发'任务尝试次数超限'事件,默认为0。这可以用于控制任务的最大尝试次数,超过该次数后,任务将被视为失败。

php think queue:listen 命令是用来监听队列任务的。

  • listen 命令是 双进程 + 管道 的处理模式。

    listen命令所在的进程会循环地创建 单次执行模式的 work 进程,每次创建的 work 进程只消费一个消息就会结束, 然后 listen 进程再创建一个新的 work 进程,

    • listen 进程会定时检查当前的 work 进程执行时间是否超过了 --timeout 参数的值, 如果已超时, 则 listen 进程会 kill 掉 work 进程, 然后抛出异常
    • listen 进程会通过管道来监听当前的 work 进程的输出, 当 work 进程有输出时, listen 进程会将输出写入到 stdout / stderr
    • listen 进程会定时通过 proc_get_status() 来监控当前的 work 进程是否仍在运行, work 进程消费完一个任务之后, work 进程就结束了,其状态会变成 terminated, 此时 listen 进程就会重新创建一个新的 work 进程并对其计时, 新的 work 进程开始消费下一个任务

php think queue:listen --queue SyncMaidoThreePcJob --memory=256 --sleep=10 --tries=3

参数可以是:

  • --queue 指定监听的队列名称。

  • --daemon 以守护进程模式运行,会持续监听并处理队列任务。

  • --delay 设置任务失败重试前的延迟时间(秒)。

  • --force 强制执行,即使任务类不存在。

  • --memory 设置最大内存使用限制,超出将退出(单位为MB)。

  • --sleep 当没有任务时,轮询间隔时间(秒)。

  • --tries 设置任务尝试次数。

相关推荐
gnicky2 分钟前
yolov10安装体验
数据库·yolo
雪精灵24 分钟前
怎么把本地的项目推到github上去
github
爬山算法29 分钟前
Oracle(148)如何进行数据库降级?
数据库·oracle
世俗ˊ30 分钟前
MySQL—触发器详解
数据库·mysql
老年DBA31 分钟前
oracle direct path read处理过程
数据库·oracle
YashanDB33 分钟前
【YashanDB知识库】如何配置jdbc驱动使getDatabaseProductName()返回Oracle
数据库·oracle·yashandb·崖山数据库·yashandb知识库
YashanDB33 分钟前
【YashanDB知识库】YMP迁移oracle不兼容给用户授权高级包
数据库·oracle·yashandb·崖山数据库·yashandb知识库
yunzhonghefei34 分钟前
[Oracle] ORA-04036: 实例使用的 PGA 内存超出 PGA_AGGREGATE_LIMIT
数据库·oracle
Week_by_week35 分钟前
11-pg内核之锁管理器(六)死锁检测
数据库
偏执网友36 分钟前
sqlserver迁移数据库文件存储位置
数据库·sqlserver·database