首页 > 解决方案 > 将失败的队列作业记录到文件回退

问题描述

如果 MySQL 出现故障,是否有任何后备选项可以将 Failed Queue Jobs 记录到文件中?

我试试

namespace App\Providers\AppServiceProvider;
function register()

Queue::failing(function (JobFailed $event)  {
    if($event->exception instanceof \PDOException){ 
        $data = [
            'code'              =>  $event->exception->getCode(),
            'connectionName'    =>  $event->connectionName,
            'getQueue'          =>  $event->job->getQueue(),
            'getRawBody'        =>  $event->job->getRawBody(),
            'exception'         =>  (string)$event->exception,
        ];
        \App\Repositories\FailedJobMysqlDown::set($data);
    }
});

但是这个检查工作的原因下降了,我想抓住插入 failed_jobs 异常

[2002] No such file or directory (SQL: insert into `failed_jobs` (`connection`, `queue`, `payload`, `exception`, `failed_at`) values (redis, superhigh, {"ty................

有任何想法吗?

谢谢

标签: laravellaravel-6laravel-7

解决方案


找到解决方案

创建类

<?php

namespace App\Override;

use Illuminate\Queue\Failed\FailedJobProviderInterface;
use Illuminate\Queue\Failed\DatabaseFailedJobProvider ;
use Illuminate\Support\Facades\Date;

class FallbackDatabaseFailedJobProvider  extends DatabaseFailedJobProvider  implements FailedJobProviderInterface
{
    public function log($connection, $queue, $payload, $exception)
    {
        try{
            return parent::log(...func_get_args());
        }catch (\Exception $e) {
            $failed_at = Date::now();
            $exception = (string) $exception;
            $data = [
                'connectionName'    =>  $connection,
                'getQueue'          =>  $queue,
                'getRawBody'        =>  $payload,
                'exception'         =>  $exception,
                'failed_at'         =>  $failed_at,
            ];
            \App\Repositories\FailedJobMysqlDown::set($data);
        }
    }
}

并在 serviceprovider 中注册

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use App\Override\FallbackDatabaseFailedJobProvider;

class FailedLogServiceProvider extends ServiceProvider
{
    public function boot()
    {
        // Get a default implementation to trigger a deferred binding
        $_ = $this->app['queue.failer'];

        // Swap the implementation
        $this->app->singleton('queue.failer', function ($app) {
            $config = $this->app['config']['queue.failed'];

            return new FallbackDatabaseFailedJobProvider($this->app['db'], $config['database'], $config['table']);
        });
    }
}

添加到提供程序中的 condig/app.php

'providers' => [
..............
App\Providers\FailedLogServiceProvider::class,
]

使用当前或创建自己的实现日志功能

<?php

namespace App\Repositories;

/**
 * Log failed job to file fallback
 */
class FailedJobMysqlDown
{
    private static $file = '_xlogJobFailedMysqlDown'; //set full path

    public static function get(){
        $x = file(self::$file);
        $data = [];
        foreach($x as $line){
            $data[] = json_decode($line);
        }
        return $data;
    }

    public static function set($message){
        $message = json_encode($message);
        file_put_contents(self::$file,$message.PHP_EOL , FILE_APPEND | LOCK_EX );
    }

}


推荐阅读