think-queue Queue::later不好用 没有延迟执行而是立即执行了?

新手上路,请多包涵

think-queue
Queue::later不好用 没有延迟执行而是立即执行了

  public function queuelater($orderid)
    {
        echo date("Y-m-d H:i:s");
        $queue=Queue::later(60, 'app\common\job\TimeoutOrder', ['orderid' => $orderid],$queue = 'OrderSure');
        if($queue){
            echo '异步执行成功';
        }else{
            echo '异步执行失败';
        }
    }

任务方法

<?php
namespace app\common\job;

use think\queue\Job;
use think\Db;
use think\facade\Log; // 导入Log门面
class TimeoutOrder
{
    // 任务执行的逻辑
    public function fire(Job $job, $data)
    // public function push(Job $job, $data)
    {
        
        // 获取订单ID
        $orderid = $data['orderid'];
        // sleep(60);
        
        $order = Db::table('re_reserve_order')->where('id', $orderid)->find();
        if ($order) {
            Db::table('re_reserve_order')
              ->where('id',$orderid)
              ->update(['is_status' => 5,'agree'=>0]); // 更改订单状态为已确认
        }
        
        if ($job->attempts() > 3) {
                  //通过这个方法可以检查这个任务已经重试了几次了
                  echo 'AAA';
        }
        
        // 删除任务标记,表示任务已完成
        $job->delete();
    }
     public function handle(Job $job, $data)
    {
        Log::record('Task started at: ' . date('Y-m-d H:i:s'), 'info');  // 输出任务开始时间
    
        // 任务执行代码...
    }


}

配置文件

return [
    'default' => 'redis',
    'connections' => [
        'sync' => [
            'driver' => 'sync',
        ],
        'database' => [
            'driver' => 'database',
            'queue' => 'default',
            'table' => 'jobs',
        ],
        'redis' => [
            'driver' => 'redis',
            'queue' => 'default',
            'host' => '127.0.0.1',
            'port' => 6379,
            'password' => '',
            'select' => 1,
            'timeout' => 0,
            'persistent' => false,
            'type'=>'redis',
        ],
    ],
    'failed' => [
        'type' => 'none',
        'table' => 'failed_jobs',
    ],
];

试过了很多次都是同步立即执行了,不知道是什么原因

阅读 229
avatarAI BotBETA

可能原因及解决方案:

  1. 驱动配置问题
    检查.envconfig/queue.php是否强制使用了sync驱动(同步驱动)。确认配置中的default驱动确实是redis。可通过临时在代码中添加dd(config('queue.default'))验证当前生效的配置。
  2. Redis队列未正确监听
    确保已启动队列监听命令:

    php think queue:listen --queue OrderSure
    # 或持久化监听
    php think queue:work --daemon --queue OrderSure
  3. Job类方法冲突
    TimeoutOrder类中同时存在fire()handle()方法会导致行为异常。保留其中一个(推荐只保留fire()方法)。
  4. 时间单位验证
    在Redis中通过redis-cli执行以下命令检查延迟队列:

    ZRANGE queues:OrderSure:delayed 0 -1 WITHSCORES

    观察时间戳是否符合预期(当前时间戳 + 60秒)

  5. 强制指定驱动测试
    在代码中临时显式指定驱动:

    Queue::later(60, TimeoutOrder::class, $data, 'OrderSure')->useConnection('redis');

调试建议:

// 在任务类中添加日志记录
public function fire(Job $job, $data) {
    Log::info('任务触发时间:'.date('Y-m-d H:i:s'));
    // ...原有逻辑...
}

然后在日志中观察实际执行时间是否符合延迟预期。

正确代码结构示例:

// 任务类简化
class TimeoutOrder {
    public function fire(Job $job, $data) {
        // 业务逻辑
        $job->delete();
    }
}

// 调用方式
Queue::later(60, \app\common\job\TimeoutOrder::class, ['orderid' => 1], 'OrderSure');
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏