Laravel如何为特定队列连接配置自定义failed_jobs表?
为Laravel队列不同连接配置独立的失败任务表
问题场景
我需要将API层的队列解耦到两个独立数据库以保障备份安全,已经在queue.php中配置了两个数据库队列连接,但默认全局的failed配置只能指定一个失败任务表,无法为每个连接单独设置自定义失败表。现有配置如下:
'connections' => [ 'database_custom' => [ 'connection' => 'mysql_custom', 'driver' => 'database', 'table' => env('QUEUE_TABLE', 'co_jobs'), 'queue' => 'default', 'retry_after' => 90, // 尝试在此添加自定义失败任务表配置但无效 ], 'database' => [ 'driver' => 'database', 'table' => env('QUEUE_TABLE', 'jobs'), 'queue' => 'default', 'retry_after' => 90, ], ], 'failed' => [ 'database' => env('DB_CONNECTION', 'mysql'), 'table' => env('QUEUE_FAILED_TABLE', 'failed_jobs'), ],
试过多种方法均未解决,求可行方案。
可行解决方案
Laravel默认不支持直接在队列连接节点下配置失败表,但可以通过以下两种方式实现需求:
方法1:自定义失败任务处理器
创建对应失败表
先为两个数据库分别生成失败任务表,比如默认连接用failed_jobs,自定义连接用co_failed_jobs:# 生成默认失败表迁移 php artisan queue:failed-table # 复制迁移文件,修改表名为co_failed_jobs,指定连接为mysql_custom执行迁移时要指定对应数据库:
php artisan migrate --database=mysql_custom编写自定义失败处理器
创建App\Queue\Failed\CustomDatabaseFailedJobProvider类,继承框架默认的数据库失败处理器:<?php namespace App\Queue\Failed; use Illuminate\Queue\Failed\DatabaseFailedJobProvider; class CustomDatabaseFailedJobProvider extends DatabaseFailedJobProvider { public function __construct($database, $table) { parent::__construct(\DB::connection($database), $table); } }绑定处理器到队列连接
在AppServiceProvider的boot方法中,为指定队列连接绑定自定义失败处理器:use App\Queue\Failed\CustomDatabaseFailedJobProvider; use Illuminate\Support\Facades\Queue; public function boot() { Queue::extendFailedProvider('database_custom', function ($app) { return new CustomDatabaseFailedJobProvider( $app['config']['queue.connections.database_custom.connection'], 'co_failed_jobs' ); }); }这样
database_custom连接的失败任务会自动写入co_failed_jobs表,默认连接仍使用全局配置的失败表。
方法2:在任务类中手动记录失败
如果不想编写自定义处理器,可在队列任务类中重写failed方法,手动将失败信息写入对应数据库的失败表:
<?php namespace App\Jobs; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; use Illuminate\Support\Facades\DB; class CustomJob implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; // 指定使用自定义队列连接 public $connection = 'database_custom'; public function handle() { // 任务业务逻辑 } public function failed(\Throwable $exception) { // 手动将失败信息写入mysql_custom连接的co_failed_jobs表 DB::connection('mysql_custom')->table('co_failed_jobs')->insert([ 'uuid' => $this->job->uuid(), 'connection' => $this->connection, 'queue' => $this->queue, 'payload' => json_encode($this->job->payload()), 'exception' => (string)$exception, 'failed_at' => now(), ]); } }
内容的提问来源于stack exchange,提问作者Marco Chirico
相关产品推荐
相关产品推荐

