laravel 队列延迟分发不生效?

一. 业务场景

在指定时间内更新订单状态,不知道这么玩对不对,希望大佬们指个路

1. 运行环境

lnmp
centerOs

1). 当前使用的 Laravel 版本?

Laravel Framework 8.78.1

2). 当前使用的 php/php-fpm 版本?

PHP 版本:7.4.21

3). 当前系统

CentOS 7.6

4). 业务环境

开发环境, 无负载均衡

5). 相关软件版本

MySQL 5.7.34;
Redis 6.2.4

2. 问题描述?

问题:延迟队列不执行,或报超时错误
错误日志:

App\Jobs\SettlementOrder has been attempted too many times or run too long. The job may have previously timed out.

env 配置文件:

BROADCAST_DRIVER=log
CACHE_DRIVER=file
FILESYSTEM_DRIVER=local
QUEUE_CONNECTION=redis
QUEUE_DRIVER=redis
REDIS_CLIENT=predis
SESSION_DRIVER=file
SESSION_LIFETIME=120

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

业务代码:

//分发任务
$jobRes = SettlementOrder::dispatch(['id' => 1])->delay(now()->addSeconds(60));

任务代码:

<?php

namespace App\Jobs;
....

class SettlementOrder implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public $data;
    public function __construct($data)
    {
        $this->data = $data;
    }
    public function handle()
    {
        /**
         * 通过交易订单ID,查询订单信息
         */
        $findOrder = DB::table('trading_record')->where('id', '=', $this->data['id'])->first();
        $oldInfo = DB::table('members')->where('id', '=', $findOrder->member_id)->first();
        if ($findOrder->status === 2 && $findOrder->result === 1) {
            $WinTotalFee = 1;//业务逻辑计算
            $winMoney = 1;//
            $up = self::updateTrading($this->data['id'], 1);
            if ($up) {
                $income = DB::table('members')->where('id', '=', $findOrder->member_id)->increment('balance', $winMoney);
                if ($income) {
                    self::balanceBack($findOrder->member_id, $findOrder->total_fee, $oldInfo->balance);
                    self::incomeFunc($findOrder->member_id, $WinTotalFee, $oldInfo->balance);
                    return true;
                }
            }
            return false;
        }
        if ($findOrder->status === 2 && $findOrder->result === 2) {
            $loseTotalFee = bcmul($findOrder->total_fee, bcdiv($findOrder->earnings, 100, 2), 2); 
            $loseMoney = bcsub($findOrder->total_fee, $loseTotalFee, 2);
            //更新
            $up = self::updateTrading($this->data['id'], 2);
            if ($up) {
                $rolBack = DB::table('members')->where('id', '=', $findOrder->member_id)->increment('balance', $loseMoney);
                if ($rolBack) {
                    self::balanceBack($findOrder->member_id, $loseMoney, $oldInfo->balance);
                    self::incomeFunc($findOrder->member_id, $loseTotalFee, $oldInfo->balance, 1);
                    return true;
                }
            }
            return false;
        }
    }

    public static function updateTrading($id, $result)
    {
        $up = DB::table('trading_record')->where('id', '=', $id)->update([
            'status' => 1,
            'result' => $result,
            'updated_at' => date('Y-m-d H:i:s', time())
        ]);
        return $up;
    }

    public static function balanceBack($memberId, $totalFee, $balance)
    {
        return DB::table('income')->insert([
            'xxx' => xxx
        ]);
    }

    public static function incomeFunc($memberId, $totalFee, $balance, $type = 0)
    {
        return DB::table('income')->insert([
            'xxx' => xxx
        ]);
    }
}

尝试过执行的监听代码:

php artisan queue:listen
php artisan queue:work
php artisan queue:work redis
php artisan queue:work redis --daemon
php artisan queue:work --daemon

3. 您期望得到的结果?

能按时执行

4. 您实际得到的结果?

队列不执行

阅读 3.3k
1 个回答

指定唯一队列,保证不堵塞(我目前是这么理解得)

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题