繁体   English   中英

如何防止 Laravel 6.x 队列调度程序多次尝试相同的作业 ID?

[英]How can I prevent Laravel 6.x Queue scheduler from trying the same Job ID multiple times?

我注意到 Laravel 正在创建相同 ID 的重复作业,例如在下面的列表中,您可以看到作业 ID 306 被尝试了两次(以及 296,298,305)

[2021-03-12 20:28:04][296] Processing: App\Jobs\RunImport
[2021-03-12 20:28:04][297] Processing: App\Jobs\RunImport
[2021-03-12 20:28:04][298] Processing: App\Jobs\RunImport
[2021-03-12 20:28:04][299] Processing: App\Jobs\RunImport
[2021-03-12 20:28:23][297] Processed:  App\Jobs\RunImport
[2021-03-12 20:28:23][300] Processing: App\Jobs\RunImport
[2021-03-12 20:28:39][301] Processing: App\Jobs\RunImport
[2021-03-12 20:28:57][301] Processed:  App\Jobs\RunImport
[2021-03-12 20:28:57][302] Processing: App\Jobs\RunImport
[2021-03-12 20:29:15][299] Processed:  App\Jobs\RunImport
[2021-03-12 20:29:15][303] Processing: App\Jobs\RunImport
[2021-03-12 20:29:35][300] Processed:  App\Jobs\RunImport
[2021-03-12 20:29:35][296] Processing: App\Jobs\RunImport
[2021-03-12 20:29:36][296] Failed:     App\Jobs\RunImport
[2021-03-12 20:29:36][298] Processing: App\Jobs\RunImport
[2021-03-12 20:29:36][298] Failed:     App\Jobs\RunImport
[2021-03-12 20:29:36][304] Processing: App\Jobs\RunImport
[2021-03-12 20:29:44][304] Processed:  App\Jobs\RunImport
[2021-03-12 20:29:44][305] Processing: App\Jobs\RunImport
[2021-03-12 20:30:05][302] Processed:  App\Jobs\RunImport
[2021-03-12 20:30:05][306] Processing: App\Jobs\RunImport
[2021-03-12 20:32:12][303] Processed:  App\Jobs\RunImport
[2021-03-12 20:32:12][305] Processing: App\Jobs\RunImport
[2021-03-12 20:32:13][305] Failed:     App\Jobs\RunImport
[2021-03-12 20:32:13][306] Processing: App\Jobs\RunImport
[2021-03-12 20:32:13][306] Failed:     App\Jobs\RunImport
[2021-03-12 20:32:13][307] Processing: App\Jobs\RunImport
[2021-03-12 20:32:43][305] Processed:  App\Jobs\RunImport
[2021-03-12 20:32:43][308] Processing: App\Jobs\RunImport
[2021-03-12 20:32:46][308] Processed:  App\Jobs\RunImport
[2021-03-12 20:32:46][309] Processing: App\Jobs\RunImport
[2021-03-12 20:32:50][309] Processed:  App\Jobs\RunImport
[2021-03-12 20:32:50][310] Processing: App\Jobs\RunImport
[2021-03-12 20:33:05][306] Processed:  App\Jobs\RunImport
[2021-03-12 20:33:09][307] Processed:  App\Jobs\RunImport
[2021-03-12 20:33:30][310] Processed:  App\Jobs\RunImport

此日志取自发送给主管的 output

[program:laravel-import]
process_name=%(program_name)s_%(process_num)02d
command=php /home/myapp/myapp-console/current/artisan queue:work --queue=import --tries=1 --timeout=21600 -vvv
autostart=true
autorestart=true
user=myapp
numprocs=4
redirect_stderr=true
stdout_logfile=/home/myapp/myapp-console/current/storage/logs/worker-import.log
stopwaitsecs=3600

我在Kernel.php中有以下时间表。 数据源是客户端特定的端点,他们可以在其中设置计划以运行导入

protected function schedule(Schedule $schedule) {
  // start jobs on import queue from user defined schedule
  $datasources = Datasource::all();
  foreach ($datasources as $datasource) {
    if (!empty($datasource->schedule) && $datasource->company->active) {
      $schedule->call(function() use ($datasource) {
        Log::channel('import-runtime')->info("Creating new import for {$datasource->datasource_key}");
        $datasource->createImport();
      })->name("datasource-{$datasource->id}")->withoutOverlapping()->cron($datasource->schedule)->runInBackground();
    }
  }
}

createImport() function 将作业添加到工作队列

public function createImport($onDemand = false) {
  $import = new Import();
  $import->datasource_id = $this->id;
  $import->status = 'awaiting';
  $import->start_at = Carbon::now();
  $import->save();
  $queue = $onDemand ? 'import-ondemand' : 'import';
  Log::channel('import-runtime')->info("[ds_{$import->datasource_id}_import_{$import->id}] Import created, adding to queue {$queue}");
  RunImport::dispatch($import)->onQueue($queue);
}

我将每个人的时间表设置为相同的 cron 格式'28 20 * * *'并让工人消耗所有工作。 然后我得到Illuminate\Queue\MaxAttemptsExceededException的错误

如何防止这些工作被多次尝试?

更改为 redis 并没有解决这个问题,同样的重复。 但是我找到了根本原因。 看起来在队列上设置--timeout=config/queue.php retry_after的 retry_after 没有影响

如果您有长时间运行的作业,则必须将--timeoutretry_after设置为您预期的最大持续时间。

我继续在queue.php中为长时间运行的进程创建了另一个连接,然后在主管中确保它使用了那个长时间运行的队列,而不是使用默认 90 秒的标准队列

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM