Laravel8的重复执行队列无效

最近业务需求需要用到队列,我就使用框架自带的队列了,使用mysql驱动程序,jobs和failed_jobs表都有了,现在就是如果队列执行失败,可以再次执行,最多5次。
参考文档最大尝试次数我的代码是这样的:

<?php

namespace App\Jobs;


use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Http;

/**
 * 出单任务
 *
 * Class PolicyOrder
 * @package App\Jobs
 */
class PolicyOrder implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $params;

    /**
     * 任务尝试次数
     *
     * @var int
     */
    public $tries = 5;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($params)
    {
        $this->params = $params;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {

            //发起出单请求
            $response = Http::asForm()->post(env("JSS_DOMAIN") . '/api/createpolicy/index', ['id'=>1]);
            $response = json_decode($response->body(), true);
            print_r($response);
    }

}

通过:php artisan queue:listen –queue=policyOrderQueue运行,成功运行了进来,但是就运行一次,我不知道哪里问题,文档就这么一句话,当我觉得少了什么。

经过一些搜索,通过$this->release()达到效果:

public function handle()
    {
        try {

                //发起出单请求
                $response = Http::asForm()->post(env("JSS_DOMAIN") . '/api/createpolicy/index', ['id'=>1]);
                $response = json_decode($response->body(), true);
                print_r($response);
                if ($response['status'] != 0) { //失败的情况
                    throw new \Exception($response['statusInfo']);
                } else {
                    //更新订单号
                    UserTrip::where(['id' => $this->params['user_trip_id']])
                        ->update(['order_no' => $response['data']['orderno']]);
                }

        } catch (\Exception $e) {
            $this->release(5); //5秒后重新放入队列,继续出单【配合$tries = 5使用】
            Log::error($e->getMessage());
        }
    }

上面代码正常,其实文档也说抛异常,我试过【只抛不要去捕获,捕获了就没有效果了】:

public function handle()
    {
                //发起出单请求
                $response = Http::asForm()->post(env("JSS_DOMAIN") . '/api/createpolicy/index', ['id'=>1]);
                $response = json_decode($response->body(), true);
                print_r($response);
                if ($response['status'] != 0) { //失败的情况
                    throw new \Exception($response['statusInfo']);
                } else {
                    //更新订单号
                    UserTrip::where(['id' => $this->params['user_trip_id']])
                        ->update(['order_no' => $response['data']['orderno']]);
                }
    }

上面这种会把异常信息存到failed_jobs表的exception字段:

下面代码也可以:

 public function handle()
    {
                //发起出单请求
                $response = Http::asForm()->post(env("JSS_DOMAIN") . '/api/createpolicy/index', ['id'=>1]);
                $response = json_decode($response->body(), true);
               // print_r($response);
                if ($response['status'] != 0) { //失败的情况
                    $this->release(5);
                } else {
                    //更新订单号
                    $res = UserTrip::where(['id' => $this->params['user_trip_id']])
                        ->update(['order_no' => $response['data']['orderno']]);

                }
            }
        } 
    }

如果还是需要捕获异常也可以这样写:

public function handle()
    {
        try {

                //发起出单请求
                $response = Http::asForm()->post(env("JSS_DOMAIN") . '/api/createpolicy/index', ['id'=>1]);
                $response = json_decode($response->body(), true);
                print_r($response);
                if ($response['status'] != 0) { //失败的情况
                    throw new \Exception($response['statusInfo']);
                } else {
                    //更新订单号
                    UserTrip::where(['id' => $this->params['user_trip_id']])
                        ->update(['order_no' => $response['data']['orderno']]);
                }

        } catch (\Exception $e) {
            Log::error($e->getMessage());
            throw $e; //抛异常,可以重新放入队列
        }
    }

在catch里面继续throw

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 14

需要用linux里类似的定时任务每隔段时间运行一次

2年前 评论
renxiaotu 2年前

你是指如果队列执行失败,可以再次执行,最多 5 次,但实际只执行一次?那你的任务要失败才行啊

2年前 评论
bluememory (楼主) 2年前
renxiaotu (作者) 2年前
bluememory (楼主) 2年前
renxiaotu (作者) 2年前
bluememory (楼主) 2年前
renxiaotu (作者) 2年前
bluememory (楼主) 2年前

之前的代码都没有抛出错误

2年前 评论
bluememory (楼主) 2年前
小李世界 (作者) 2年前
bluememory (楼主) 2年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!