本文目录导读:

Laravel 的重试机制主要涉及队列任务重试和HTTP 请求重试两个核心场景,下面分别介绍配置方法。
队列任务重试
1 配置最大尝试次数
在 config/queue.php 中配置全局重试次数:
// config/queue.php
'connections' => [
'database' => [
'driver' => 'database',
'table' => 'jobs',
'queue' => 'default',
'retry_after' => 90, // 任务超时时间(秒)
'max_attempts' => 3, // 最大重试次数
],
'redis' => [
'driver' => 'redis',
'connection' => 'default',
'queue' => 'default',
'retry_after' => 90,
'block_for' => null,
'max_attempts' => 3,
],
],
2 任务级别配置(推荐)
在任务类中定义 $tries 属性:
class ProcessPodcast implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $tries = 3; // 最大重试次数
public function handle()
{
// 任务逻辑
}
}
3 配置重试延迟
在任务类中定义 backoff 方法:
class ProcessPodcast implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $tries = 3;
/**
* 重试延迟时间(秒)
*/
public function backoff()
{
return [2, 5, 10]; // 第1次重试等待2秒,第2次5秒,第3次10秒
}
}
或者使用常量方式:
class ProcessPodcast implements ShouldQueue
{
public $backoff = 5; // 每次重试等待5秒
}
HTTP 请求重试
1 使用 Laravel HTTP 客户端
use Illuminate\Support\Facades\Http;
$response = Http::retry(3, 100, function ($exception) {
// 仅在特定条件下重试
return $exception instanceof ConnectionException;
})->post('https://api.example.com/users');
参数说明:
- 第一个参数:重试次数
- 第二个参数:重试间隔(毫秒)
- 第三个参数:可选的回调,决定是否重试
2 设置重试延迟策略
$response = Http::retry(3, function ($attempt) {
// 指数退避策略:第1次100ms,第2次200ms,第3次400ms
return 100 * pow(2, $attempt - 1);
})->get('https://api.example.com');
自定义重试逻辑
1 在任务中手动重试
class ProcessPodcast implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $tries = 5;
public function handle()
{
try {
// 任务逻辑
if (someCondition()) {
throw new \Exception('处理失败');
}
} catch (\Exception $e) {
// 释放任务回队列进行重试
if ($this->attempts() < $this->tries) {
$this->release(30); // 30秒后重试
return;
}
// 达到最大重试次数,标记为失败
$this->fail($e);
}
}
}
2 自定义失败处理
创建 App\Exceptions\Handler 中的 failed 方法:
// app/Exceptions/Handler.php
protected function failed(Throwable $exception, $failedJob)
{
// 记录失败日志
Log::error('Job failed: ' . $failedJob->payload(), [
'exception' => $exception
]);
// 发送通知
Notification::route('mail', 'admin@example.com')
->notify(new JobFailedNotification($failedJob, $exception));
}
高级配置示例
1 唯一任务(避免重复执行)
class ProcessPodcast implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, ShouldBeUnique;
public $uniqueFor = 3600; // 1小时内唯一
public $tries = 3;
public $maxExceptions = 2; // 最多异常次数
public function handle()
{
// 处理逻辑
}
}
2 配置队列工作器
命令行启动工作器时指定参数:
# 运行队列工作器,最多尝试3次 php artisan queue:work --tries=3 # 指定队列 php artisan queue:work --queue=high,default --tries=3 # 设置超时时间 php artisan queue:work --timeout=60 --tries=3 # 设置睡眠时间(无任务时) php artisan queue:work --sleep=3 --tries=3
3 自定义重试中间件
namespace App\Queue\Middleware;
class RetryMiddleware
{
public function handle($job, $next)
{
try {
return $next($job);
} catch (\Exception $e) {
// 自定义重试逻辑
if ($job->attempts() > 5) {
throw $e;
}
// 根据异常类型决定延迟
$delay = $e instanceof RateLimitException ? 60 : 10;
$job->release($delay);
}
}
}
在任务中使用:
class ProcessPodcast implements ShouldQueue
{
public function middleware()
{
return [new RetryMiddleware];
}
}
数据库级别的重试
1 配置数据库重试
// config/database.php
'mysql' => [
'driver' => 'mysql',
// ... 其他配置
'options' => [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => true,
],
'read' => [
'retry' => [
'attempts' => 3,
'delay' => 100, // 毫秒
],
],
],
最佳实践建议
- 指数退避策略:重试间隔逐渐增大,避免服务器压力
- 有限重试次数:设置合理上限(3-5 次)
- 重试幂等性:确保重试不会产生副作用
- 监控告警:记录重试和失败日志
- 区分错误类型:临时错误重试,永久错误直接失败
如果需要更复杂的重试策略,可以考虑使用专门的包如 spatie/laravel-queueable-action 或 spatie/backoff。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播