首页 文章

Laravel:如何使Redis排队的作业失败?

提问于
浏览
3

在Laravel运行Redis队列时,我无法在Job类中调用 failed 方法 . 我想确保我能正确记录它们并将它们写入failed_jobs表 .

关于队列的Laravel文档states

您可以直接在作业类上定义失败的方法,允许您在发生故障时执行特定于作业的清理 . 这是向用户发送警报或恢复作业执行的任何操作的理想位置 . 导致作业失败的异常将传递给失败的方法:

我出现在我的日志中的是 It did not workexception caught .

我使用以下命令启动此队列,特别是将 tries 设置为1,因此它不会尝试重新运行该作业 .

php artisan queue:work redis --queue=widgets --tries=1

如何调用失败的方法并将作业显示在failed_jobs表中?

<?php
namespace App\Jobs;
use Exception;
use App\Processors\WidgetProcessor;

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

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

    public function __construct($widget)
    {
        $this->widget = $widget;
    }

    public function handle(WidgetProcessor $processor)
    {
        Redis::throttle('WidgetJob')->allow(5)->every(60)->then(function () use ($processor) {
            try {
                $var = false;
                if($var == false) {
                    Log::notice('It did not work');
                    throw new Exception;
                } else {
                    Log::notice('It worked');
                }
            } catch(Exception $e) {
                Log::notice('Exception caught');
            }          
        }, function () {
            return $this->release(5);
        });
    }

    public function failed(Exception $exception)
    {
        Log::notice('failed was called');
    }
}

1 回答

  • 2

    Laravel Queue系统作为一个守护进程,可以获取作业,运行它们并继续前进 . 如果你的工作被抛出异常,Laravel会认为这是一项成功的工作 . 您的代码段中的问题是:

    try {
      ... 
    } catch(Exception $e) {
        Log::notice('Exception caught');
    }
    

    通过捕获异常,您不要让Laravel将此作业标记为失败 .

    这里有两个选择:要么不使用 try...catch ,要么如果你真的想使用它,请按如下方式重新抛出异常:

    try {
      ... 
    } catch(Exception $e) {
        Log::notice('Exception caught');
    
        throw $e;
    }
    

    通过让异常冒出来,Laravel将失败并调用你的 failed() 例行程序 .

相关问题