在 Laravel 9 中,队列任务的 超时 的验证(sleep() 不能够使用,会导致相关设置不起作用)
1、在 Laravel 9 中,队列任务的超时。决定尝试验证一下,在任务类中的实现如下。最后发现在 Windows 系统中 未生效。原因在于,须安装 pcntl PHP 扩展以指定任务超时。但是此扩展在 Windows 平台上不可用。如图1
public $timeout = 2; /** * Execute the job. * * @return void */ public function handle() { sleep(10); Log::info( 'handle5', [ date('Y-m-d H:i:s') ] ); }
2、决定在 Linux 系统中执行队列任务。超时时间设置已经生效。队列作业执行失败。生成的日志符合预期。如图2
public $timeout = 300; public function handle() { Log::info( 'handle-timeout20-before', [ date('Y-m-d H:i:s') ] ); sleep(600); Log::info( 'handle-timeout20-after', [ date('Y-m-d H:i:s') ] ); // 其他流程实现 Log::info( 'handle-timeout20-updateJobStatus-after', [ date('Y-m-d H:i:s') ] ); } /** * @param \Throwable $e * @return void */ public function failed(\Throwable $e) { Log::error('导出订单交运日志信息异常:' . $e->getFile() . $e->getLine() . $e->getMessage()); }
[2024-05-13 02:13:58] feature.INFO: handle-timeout20-before ["2024-05-13 02:13:58"] [2024-05-13 02:18:58] feature.ERROR: 导出订单交运日志信息异常:/var/www/backend/vendor/laravel/framework/src/Illuminate/Queue/Worker.php755Modules\Order\Jobs\OrderShippingLogExportJob has been attempted too many times or run too long. The job may have previously timed out.
3、在表 failed_jobs 中,搜索:`exception` LIKE ‘%OrderShippingLogExportJob%’,可以搜索到相应的记录。查看字段 exception 的值如下所示。如图3
Illuminate\Queue\MaxAttemptsExceededException: Modules\Order\Jobs\OrderShippingLogExportJob has been attempted too many times or run too long. The job may have previously timed out. in /var/www/backend/vendor/laravel/framework/src/Illuminate/Queue/Worker.php:755 Stack trace: #0 /var/www/backend/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(214): Illuminate\Queue\Worker->maxAttemptsExceededException(Object(Illuminate\Queue\Jobs\RedisJob)) #1 /var/www/backend/Modules/Order/Jobs/OrderShippingLogExportJob.php(65): Illuminate\Queue\Worker->Illuminate\Queue\{closure}(14, Array) #2 /var/www/backend/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Modules\Order\Jobs\OrderShippingLogExportJob->handle() #3 /var/www/backend/vendor/laravel/framework/src/Illuminate/Container/Util.php(41): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}() #4 /var/www/backend/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(93): Illuminate\Container\Util::unwrapIfClosure(Object(Closure)) #5 /var/www/backend/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(37): Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Array, Object(Closure)) #6 /var/www/backend/vendor/laravel/framework/src/Illuminate/Container/Container.php(651): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), Array, Array, NULL) #7 /var/www/backend/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(128): Illuminate\Container\Container->call(Array) #8 /var/www/backend/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(141): Illuminate\Bus\Dispatcher->Illuminate\Bus\{closure}(Object(Modules\Order\Jobs\OrderShippingLogExportJob)) #9 /var/www/backend/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(116): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Modules\Order\Jobs\OrderShippingLogExportJob)) #10 /var/www/backend/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(132): Illuminate\Pipeline\Pipeline->then(Object(Closure)) #11 /var/www/backend/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(124): Illuminate\Bus\Dispatcher->dispatchNow(Object(Modules\Order\Jobs\OrderShippingLogExportJob), false) #12 /var/www/backend/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(141): Illuminate\Queue\CallQueuedHandler->Illuminate\Queue\{closure}(Object(Modules\Order\Jobs\OrderShippingLogExportJob)) #13 /var/www/backend/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(116): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Modules\Order\Jobs\OrderShippingLogExportJob)) #14 /var/www/backend/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(126): Illuminate\Pipeline\Pipeline->then(Object(Closure)) #15 /var/www/backend/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(70): Illuminate\Queue\CallQueuedHandler->dispatchThroughMiddleware(Object(Illuminate\Queue\Jobs\RedisJob), Object(Modules\Order\Jobs\OrderShippingLogExportJob)) #16 /var/www/backend/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(98): Illuminate\Queue\CallQueuedHandler->call(Object(Illuminate\Queue\Jobs\RedisJob), Array) #17 /var/www/backend/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(425): Illuminate\Queue\Jobs\Job->fire() #18 /var/www/backend/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(375): Illuminate\Queue\Worker->process('redis', Object(Illuminate\Queue\Jobs\RedisJob), Object(Illuminate\Queue\WorkerOptions)) #19 /var/www/backend/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(173): Illuminate\Queue\Worker->runJob(Object(Illuminate\Queue\Jobs\RedisJob), 'redis', Object(Illuminate\Queue\WorkerOptions)) #20 /var/www/backend/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(150): Illuminate\Queue\Worker->daemon('redis', 'export_queue', Object(Illuminate\Queue\WorkerOptions)) #21 /var/www/backend/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(134): Illuminate\Queue\Console\WorkCommand->runWorker('redis', 'export_queue') #22 /var/www/backend/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Illuminate\Queue\Console\WorkCommand->handle() #23 /var/www/backend/vendor/laravel/framework/src/Illuminate/Container/Util.php(41): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}() #24 /var/www/backend/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(93): Illuminate\Container\Util::unwrapIfClosure(Object(Closure)) #25 /var/www/backend/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(37): Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Array, Object(Closure)) #26 /var/www/backend/vendor/laravel/framework/src/Illuminate/Container/Container.php(651): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), Array, Array, NULL) #27 /var/www/backend/vendor/laravel/framework/src/Illuminate/Console/Command.php(144): Illuminate\Container\Container->call(Array) #28 /var/www/backend/vendor/symfony/console/Command/Command.php(312): Illuminate\Console\Command->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle)) #29 /var/www/backend/vendor/laravel/framework/src/Illuminate/Console/Command.php(126): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle)) #30 /var/www/backend/vendor/symfony/console/Application.php(1022): Illuminate\Console\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #31 /var/www/backend/vendor/symfony/console/Application.php(314): Symfony\Component\Console\Application->doRunCommand(Object(Illuminate\Queue\Console\WorkCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #32 /var/www/backend/vendor/symfony/console/Application.php(168): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #33 /var/www/backend/vendor/laravel/framework/src/Illuminate/Console/Application.php(102): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #34 /var/www/backend/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(151): Illuminate\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #35 /var/www/backend/artisan(37): Illuminate\Foundation\Console\Kernel->handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #36 {main}
4、定义任务类本身的最大尝试次数 为 2,在任务类中的实现如下。第1次验证后,不符合预期,由于 超时设置为 300 秒,而队列 sleep(600),所以理论上来说,无论怎样,队列任务皆不应该执行成功才是。可是竟然有执行成功的相关日志信息。第2次与第3次验证,也不太符合预期。没有执行成功,但是也没有执行失败。而是一直卡在进行中的环节,且没有抛出超时异常的信息(通过在表 failed_jobs 中,搜索:`exception` LIKE ‘%OrderShippingLogExportJob%’,没有搜索到相应的记录)。预期是:在1次队列任务执行过程中,handle-timeout20-$tries2-before 应该出现 2 次,且最后队列任务执行失败,会运行方法 failed。
/** * 在超时之前任务可以运行的秒数. * * @var int */ public $timeout = 300; public $tries = 2; use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; private JobStatus $jobStatus; private array $params; /** * Create a new job instance. * * @return void */ public function __construct(JobStatus $jobStatus, array $params) { $this->jobStatus = $jobStatus; $this->params = $params; $this->onQueue(OrderConstants::EXPORT_QUEUE); } /** * Execute the job. * * @return void */ public function handle() { $orderShippingLogService = app(OrderShippingLogService::class); Log::info( 'handle-timeout20-$tries2-before', [ date('Y-m-d H:i:s') ] ); sleep(600); Log::info( 'handle-timeout20-$tries2-after', [ date('Y-m-d H:i:s') ] ); // Log::info( 'handle-timeout20-$tries2-updateJobStatus-after', [ date('Y-m-d H:i:s') ] ); } /** * @param \Throwable $e * @return void */ public function failed(\Throwable $e) { Log::error('导出订单交运日志信息异常:' . $e->getFile() . $e->getLine() . $e->getMessage()); }
[2024-05-13 06:51:06] feature.INFO: handle-timeout20-$tries2-before ["2024-05-13 06:51:06"] [2024-05-13 06:56:01] feature.INFO: handle-timeout20-$tries2-after ["2024-05-13 06:56:01"] [2024-05-13 06:56:01] feature.INFO: handle-timeout20-$tries2-updateJobStatus-after ["2024-05-13 06:56:01"] [2024-05-13 07:12:46] feature.INFO: handle-timeout20-$tries2-before ["2024-05-13 07:12:46"] [2024-05-13 07:24:49] feature.INFO: handle-timeout20-$tries2-before ["2024-05-13 07:24:49"]
5、决定添加 超时失败,如果您希望在超时时将任务标记为 failed,可以在任务类上定义 $failOnTimeout 属性。没有执行成功,但是也没有执行失败。而是一直卡在进行中的环节,且没有抛出超时异常的信息(通过在表 failed_jobs 中,搜索:`exception` LIKE ‘%OrderShippingLogExportJob%’,没有搜索到相应的记录)。预期是:在队列任务执行过程中,handle-timeout20-$tries2-$failOnTimeout-before 应该出现 2 次,且最后队列任务执行失败,会运行方法 failed。初步的结论是:当 $tries 大于 1 时,$timeout 的设置好像不生效似的。
/** * 在超时之前任务可以运行的秒数. * * @var int */ public $timeout = 300; public $tries = 2; public $failOnTimeout = true; use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; private JobStatus $jobStatus; private array $params; /** * Create a new job instance. * * @return void */ public function __construct(JobStatus $jobStatus, array $params) { $this->jobStatus = $jobStatus; $this->params = $params; $this->onQueue(OrderConstants::EXPORT_QUEUE); } /** * Execute the job. * * @return void */ public function handle() { $orderShippingLogService = app(OrderShippingLogService::class); Log::info( 'handle-timeout20-$tries2-$failOnTimeout-before', [ date('Y-m-d H:i:s') ] ); sleep(600); Log::info( 'handle-timeout20-$tries2-$failOnTimeout-after', [ date('Y-m-d H:i:s') ] ); // Log::info( 'handle-timeout20-$tries2-$failOnTimeout-updateJobStatus-after', [ date('Y-m-d H:i:s') ] ); } /** * @param \Throwable $e * @return void */ public function failed(\Throwable $e) { Log::error('导出订单交运日志信息异常:' . $e->getFile() . $e->getLine() . $e->getMessage()); }
[2024-05-13 07:50:20] feature.INFO: handle-timeout20-$tries2-$failOnTimeout-before ["2024-05-13 07:50:20"]
6、验证当 $tries 等于 1 时,$timeout 的设置 与 $failOnTimeout = true。以与步骤2进行比较。确认 $failOnTimeout = true 是否有效。最终发现与步骤2没有区别。感觉 $failOnTimeout = true 没有作用了。
/** * 在超时之前任务可以运行的秒数. * * @var int */ public $timeout = 300; public $tries = 1; public $failOnTimeout = true; use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; private JobStatus $jobStatus; private array $params; /** * Create a new job instance. * * @return void */ public function __construct(JobStatus $jobStatus, array $params) { $this->jobStatus = $jobStatus; $this->params = $params; $this->onQueue(OrderConstants::EXPORT_QUEUE); } /** * Execute the job. * * @return void */ public function handle() { $orderShippingLogService = app(OrderShippingLogService::class); Log::info( 'handle-timeout20-$tries1-$failOnTimeout-before', [ date('Y-m-d H:i:s') ] ); sleep(600); Log::info( 'handle-timeout20-$tries1-$failOnTimeout-after', [ date('Y-m-d H:i:s') ] ); // Log::info( 'handle-timeout20-$tries1-$failOnTimeout-updateJobStatus-after', [ date('Y-m-d H:i:s') ] ); } /** * @param \Throwable $e * @return void */ public function failed(\Throwable $e) { Log::error('导出订单交运日志信息异常:' . $e->getFile() . $e->getLine() . $e->getMessage()); }
[2024-05-13 09:38:29] feature.INFO: handle-timeout120-$tries2-$failOnTimeout-before ["2024-05-13 09:38:29"] [2024-05-13 09:38:29] feature.INFO: andle-timeout120-$tries2-$failOnTimeout-after ["2024-05-13 09:38:29"] [2024-05-13 09:40:29] feature.ERROR: 导出订单交运日志信息异常:/var/www/backend/vendor/laravel/framework/src/Illuminate/Queue/Worker.php755Modules\Order\Jobs\OrderShippingLogExportJob has been attempted too many times or run too long. The job may have previously timed out.
7、重新验证步骤 4,去掉 $failOnTimeout = true ,去掉 sleep(),而是采用其他的方案来让 Job 执行超时。队列皆败了,且执行了 failed 方法,且 andle-timeout120-$tries2-$failOnTimeout-updateJobStatus-after 未执行到。基本符合预期(预期 handle-timeout120-$tries2-$failOnTimeout-before 会执行 2 次)。得出结论:sleep 方法确认会让尝试次数设置受到影响了。
/** * 在超时之前任务可以运行的秒数. * * @var int */ public $timeout = 120; public $tries = 2; // public $failOnTimeout = true; use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; /** * Execute the job. * * @return void */ public function handle() { Log::info( 'handle-timeout120-$tries2-$failOnTimeout-before', [ date('Y-m-d H:i:s') ] ); // sleep(600); Log::info( 'andle-timeout120-$tries2-$failOnTimeout-after', [ date('Y-m-d H:i:s') ] ); // 此环节超时 Log::info( 'andle-timeout120-$tries2-$failOnTimeout-updateJobStatus-after', [ date('Y-m-d H:i:s') ] ); } /** * @param \Throwable $e * @return void */ public function failed(\Throwable $e) { Log::error('导出订单交运日志信息异常:' . $e->getFile() . $e->getLine() . $e->getMessage()); $this->updateJobStatus(JobStatusConstant::STATUS_FAIL); }
[2024-05-13 08:56:25] feature.INFO: handle-timeout120-$tries2-$failOnTimeout-before ["2024-05-13 08:56:25"] [2024-05-13 08:56:25] feature.INFO: andle-timeout120-$tries2-$failOnTimeout-after ["2024-05-13 08:56:25"] [2024-05-13 08:58:25] feature.ERROR: 导出订单交运日志信息异常:/var/www/backend/vendor/laravel/framework/src/Illuminate/Queue/Worker.php755Modules\Order\Jobs\OrderShippingLogExportJob has been attempted too many times or run too long. The job may have previously timed out. [2024-05-13 09:19:27] feature.INFO: handle-timeout120-$tries2-$failOnTimeout-before ["2024-05-13 09:19:27"] [2024-05-13 09:19:27] feature.INFO: andle-timeout120-$tries2-$failOnTimeout-after ["2024-05-13 09:19:27"] [2024-05-13 09:21:27] feature.ERROR: 导出订单交运日志信息异常:/var/www/backend/vendor/laravel/framework/src/Illuminate/Queue/Worker.php755Modules\Order\Jobs\OrderShippingLogExportJob has been attempted too many times or run too long. The job may have previously timed out. [2024-05-13 09:22:43] feature.INFO: handle-timeout120-$tries2-$failOnTimeout-before ["2024-05-13 09:22:43"] [2024-05-13 09:22:43] feature.INFO: andle-timeout120-$tries2-$failOnTimeout-after ["2024-05-13 09:22:43"] [2024-05-13 09:24:43] feature.ERROR: 导出订单交运日志信息异常:/var/www/backend/vendor/laravel/framework/src/Illuminate/Queue/Worker.php755Modules\Order\Jobs\OrderShippingLogExportJob has been attempted too many times or run too long. The job may have previously timed out.
8、重新验证步骤 5,决定去掉 sleep(),而是采用其他的方案来让 Job 执行超时。验证了3次,队列皆失败了,且皆执行了 failed 方法,且 andle-timeout120-$tries2-$failOnTimeout-updateJobStatus-after 皆未执行到。基本符合预期(预期 handle-timeout120-$tries2-$failOnTimeout-before 会执行 2 次)。得出结论:sleep 方法确认会让尝试次数设置受到影响了。如图4
/** * 在超时之前任务可以运行的秒数. * * @var int */ public $timeout = 120; public $tries = 2; public $failOnTimeout = true; use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; /** * Execute the job. * * @return void */ public function handle() { Log::info( 'handle-timeout120-$tries2-$failOnTimeout-before', [ date('Y-m-d H:i:s') ] ); // sleep(600); Log::info( 'andle-timeout120-$tries2-$failOnTimeout-after', [ date('Y-m-d H:i:s') ] ); // 此环节超时 Log::info( 'andle-timeout120-$tries2-$failOnTimeout-updateJobStatus-after', [ date('Y-m-d H:i:s') ] ); } /** * @param \Throwable $e * @return void */ public function failed(\Throwable $e) { Log::error('导出订单交运日志信息异常:' . $e->getFile() . $e->getLine() . $e->getMessage()); $this->updateJobStatus(JobStatusConstant::STATUS_FAIL); }
[2024-05-13 08:56:25] feature.INFO: handle-timeout120-$tries2-$failOnTimeout-before ["2024-05-13 08:56:25"] [2024-05-13 08:56:25] feature.INFO: andle-timeout120-$tries2-$failOnTimeout-after ["2024-05-13 08:56:25"] [2024-05-13 08:58:25] feature.ERROR: 导出订单交运日志信息异常:/var/www/backend/vendor/laravel/framework/src/Illuminate/Queue/Worker.php755Modules\Order\Jobs\OrderShippingLogExportJob has been attempted too many times or run too long. The job may have previously timed out. [2024-05-13 09:19:27] feature.INFO: handle-timeout120-$tries2-$failOnTimeout-before ["2024-05-13 09:19:27"] [2024-05-13 09:19:27] feature.INFO: andle-timeout120-$tries2-$failOnTimeout-after ["2024-05-13 09:19:27"] [2024-05-13 09:21:27] feature.ERROR: 导出订单交运日志信息异常:/var/www/backend/vendor/laravel/framework/src/Illuminate/Queue/Worker.php755Modules\Order\Jobs\OrderShippingLogExportJob has been attempted too many times or run too long. The job may have previously timed out. [2024-05-13 09:22:43] feature.INFO: handle-timeout120-$tries2-$failOnTimeout-before ["2024-05-13 09:22:43"] [2024-05-13 09:22:43] feature.INFO: andle-timeout120-$tries2-$failOnTimeout-after ["2024-05-13 09:22:43"] [2024-05-13 09:24:43] feature.ERROR: 导出订单交运日志信息异常:/var/www/backend/vendor/laravel/framework/src/Illuminate/Queue/Worker.php755Modules\Order\Jobs\OrderShippingLogExportJob has been attempted too many times or run too long. The job may have previously timed out.
9、将尝试次数设置为 4 次,取消 $failOnTimeout = true。不符合预期,预期 handle-timeout120-$tries2-$failOnTimeout-before 执行 4 次。实际上只有 1 次,且既无成功,也无失败,而是一直卡住了。
/** * 在超时之前任务可以运行的秒数. * * @var int */ public $timeout = 120; public $tries = 4; // public $failOnTimeout = true; use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; /** * Execute the job. * * @return void */ public function handle() { Log::info( 'handle-timeout120-$tries2-$failOnTimeout-before', [ date('Y-m-d H:i:s') ] ); // sleep(600); Log::info( 'andle-timeout120-$tries2-$failOnTimeout-after', [ date('Y-m-d H:i:s') ] ); // 此环节超时 Log::info( 'andle-timeout120-$tries2-$failOnTimeout-updateJobStatus-after', [ date('Y-m-d H:i:s') ] ); } /** * @param \Throwable $e * @return void */ public function failed(\Throwable $e) { Log::error('导出订单交运日志信息异常:' . $e->getFile() . $e->getLine() . $e->getMessage()); $this->updateJobStatus(JobStatusConstant::STATUS_FAIL); }
[2024-05-13 09:51:02] feature.INFO: handle-timeout120-$tries2-$failOnTimeout-before ["2024-05-13 09:51:02"] [2024-05-13 09:51:02] feature.INFO: andle-timeout120-$tries2-$failOnTimeout-after ["2024-05-13 09:51:02"] [2024-05-13 10:03:33] feature.INFO: handle-timeout120-$tries2-$failOnTimeout-before ["2024-05-13 10:03:33"] [2024-05-13 10:03:33] feature.INFO: andle-timeout120-$tries2-$failOnTimeout-after ["2024-05-13 10:03:33"]
10、将尝试次数设置为 4 次,设置 $failOnTimeout = true。基本符合预期,预期 handle-timeout120-$tries2-$failOnTimeout-before 执行 4 次。实际上只有 1 次,但是执行失败(符合预期)了。
/** * 在超时之前任务可以运行的秒数. * * @var int */ public $timeout = 120; public $tries = 4; public $failOnTimeout = true; use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; /** * Execute the job. * * @return void */ public function handle() { Log::info( 'handle-timeout120-$tries2-$failOnTimeout-before', [ date('Y-m-d H:i:s') ] ); // sleep(600); Log::info( 'andle-timeout120-$tries2-$failOnTimeout-after', [ date('Y-m-d H:i:s') ] ); // 此环节超时 Log::info( 'andle-timeout120-$tries2-$failOnTimeout-updateJobStatus-after', [ date('Y-m-d H:i:s') ] ); } /** * @param \Throwable $e * @return void */ public function failed(\Throwable $e) { Log::error('导出订单交运日志信息异常:' . $e->getFile() . $e->getLine() . $e->getMessage()); $this->updateJobStatus(JobStatusConstant::STATUS_FAIL); }
[2024-05-13 11:13:54] feature.INFO: handle-timeout120-$tries2-$failOnTimeout-before ["2024-05-13 11:13:54"] [2024-05-13 11:13:54] feature.INFO: andle-timeout120-$tries2-$failOnTimeout-after ["2024-05-13 11:13:54"] [2024-05-13 11:15:54] feature.ERROR: 导出订单交运日志信息异常:/var/www/backend/vendor/laravel/framework/src/Illuminate/Queue/Worker.php755Modules\Order\Jobs\OrderShippingLogExportJob has been attempted too many times or run too long. The job may have previously timed out.
11、将尝试次数设置为 3 次,设置重试任务前等待的秒数 $backoff = 6。验证了2次,结果是一样的。基本符合预期,预期 handle-timeout120-$backoff6-$tries3-$failOnTimeout-before 执行 3 次,实际上只有 2 次,但是执行成功(不符合预期)了。
// 在超时之前任务可以运行的秒数 public int $timeout = 120; // 重试任务前等待的秒数 public int $backoff = 6; // 任务可尝试次数 public int $tries = 3; // 标示是否应在超时时标记为失败 // public bool $failOnTimeout = true; /** * Execute the job. * * @return void */ public function handle() { $orderShippingLogService = app(OrderShippingLogService::class); Log::info( 'handle-timeout120-$backoff6-$tries3-$failOnTimeout-before', [ date('Y-m-d H:i:s') ] ); // sleep(600); // Log::info( // 'handle-timeout120-$backoff6-$tries3-$failOnTimeout-after', // [ // date('Y-m-d H:i:s') // ] // ); // 执行超时 Log::info( 'handle-timeout120-$backoff6-$tries3-$failOnTimeout-updateJobStatus-after', [ date('Y-m-d H:i:s') ] ); } /** * @param \Throwable $e * @return void */ public function failed(\Throwable $e) { Log::error('导出订单交运日志信息异常:' . $e->getFile() . $e->getLine() . $e->getMessage()); $this->updateJobStatus(JobStatusConstant::STATUS_FAIL); }
[2024-05-14 07:19:22] feature.INFO: handle-timeout120-$backoff6-$tries3-$failOnTimeout-before ["2024-05-14 07:19:22"] [2024-05-14 07:24:49] feature.INFO: handle-timeout120-$backoff6-$tries3-$failOnTimeout-before ["2024-05-14 07:24:49"] [2024-05-14 07:25:21] feature.INFO: handle-timeout120-$backoff6-$tries3-$failOnTimeout-updateJobStatus-after ["2024-05-14 07:25:21"] [2024-05-14 07:41:38] feature.INFO: handle-timeout120-$backoff6-$tries3-$failOnTimeout-before ["2024-05-14 07:41:38"] [2024-05-14 07:50:20] feature.INFO: handle-timeout120-$backoff6-$tries3-$failOnTimeout-before ["2024-05-14 07:50:20"] [2024-05-14 07:50:52] feature.INFO: handle-timeout120-$backoff6-$tries3-$failOnTimeout-updateJobStatus-after ["2024-05-14 07:50:52"]
12、将尝试次数设置为 3 次,设置重试任务前等待的秒数 $backoff = 6,设置 $failOnTimeout = true。基本符合预期,预期 handle-timeout120-$backoff6-$tries3-$failOnTimeout-before 执行 3 次,实际上只有 1 次,但是执行失败(符合预期)了。
// 在超时之前任务可以运行的秒数 public int $timeout = 120; // 重试任务前等待的秒数 public int $backoff = 6; // 任务可尝试次数 public int $tries = 3; // 标示是否应在超时时标记为失败 // public bool $failOnTimeout = true; /** * Execute the job. * * @return void */ public function handle() { $orderShippingLogService = app(OrderShippingLogService::class); Log::info( 'handle-timeout120-$backoff6-$tries3-$failOnTimeout-before', [ date('Y-m-d H:i:s') ] ); // sleep(600); // Log::info( // 'handle-timeout120-$backoff6-$tries3-$failOnTimeout-after', // [ // date('Y-m-d H:i:s') // ] // ); // 执行超时 Log::info( 'handle-timeout120-$backoff6-$tries3-$failOnTimeout-updateJobStatus-after', [ date('Y-m-d H:i:s') ] ); } /** * @param \Throwable $e * @return void */ public function failed(\Throwable $e) { Log::error('导出订单交运日志信息异常:' . $e->getFile() . $e->getLine() . $e->getMessage()); $this->updateJobStatus(JobStatusConstant::STATUS_FAIL); }
[2024-05-14 10:09:55] feature.INFO: handle-timeout120-$backoff6-$tries3-$failOnTimeout-before ["2024-05-14 10:09:55"] [2024-05-14 10:11:55] feature.ERROR: 导出订单交运日志信息异常:/var/www/backend/vendor/laravel/framework/src/Illuminate/Queue/Worker.php755Modules\Order\Jobs\OrderShippingLogExportJob has been attempted too many times or run too long. The job may have previously timed out.
13、最终决定,配置如下
// 在超时之前任务可以运行的秒数 public int $timeout = 120; // 任务可尝试次数 public int $tries = 1; // 标示是否应在超时时标记为失败 public bool $failOnTimeout = true;
近期评论