php - Laravel:如何使 Redis 排队作业失败?
问题描述
在 Laravel 中运行 Redis 队列时,我无法获取failed
Job 类中调用的方法。我想确保我可以正确记录它们并将它们写入 failed_jobs 表。
关于队列状态的 Laravel 文档
您可以直接在您的作业类上定义一个失败的方法,允许您在发生故障时执行特定于作业的清理。这是向您的用户发送警报或恢复作业执行的任何操作的理想位置。导致作业失败的异常将被传递给失败的方法:
我不是 100% 确定 Laravel 认为什么是“导致工作失败的异常”。下面是一个非常简单的工作类。我的日志中出现的所有内容都是It did not work
and exception 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');
}
}
解决方案
Laravel 队列系统作为一个守护进程工作,它负责接收作业、运行它们并继续前进。如果你的工作从不抛出异常,Laravel 会认为它是一个成功的工作。您的代码段中的问题是:
try {
...
} catch(Exception $e) {
Log::notice('Exception caught');
}
通过捕获异常,您不会让 Laravel 将此作业标记为失败。
您在这里有两个选择:要么不使用try...catch
,要么如果您真的想使用它,请重新抛出异常,如下所示:
try {
...
} catch(Exception $e) {
Log::notice('Exception caught');
throw $e;
}
通过让异常冒泡,Laravel 将使工作失败并调用您的failed()
例程。
推荐阅读
- mysql - #1022 重复的外键 - MySQL 错误
- python - 在 python 中使用 OOP 更改 bin 的格式
- solr - 如何在 solr 中自动忽略未知字段
- sorting - 使用交叉过滤器对 IP 地址字段进行排序
- javascript - Firefox 不断提示在单页应用上保存密码
- python - 如何使用openpyxl修改python中特定工作表中的数据
- nomad - Hashicorp Nomad 在启动后杀死了 zookeeper 进程
- amazon-s3 - 使用 s3cmd 排除同步到 AmazonS3 的子文件夹
- swift - RxSwift 使用 RxCocoa 绑定到动画
- firebase - 将 Firebase 崩溃报告更新到 Firebase Crashlytics:仍在旧仪表板上