指数退避算法是一种网络错误处理策略,用于在客户端重试失败的请求时,增加每次重试之间的延迟时间。这种算法旨在避免连续的请求冲突,并提高网络资源的利用率。
当客户端在网络请求失败后,不是立即重试,而是等待一段固定的时间间隔后再进行重试。这个时间间隔会随着重试次数的增加而呈指数级增长。例如,第一次重试可能等待1秒,第二次重试等待2秒,第三次重试等待4秒,依此类推。
公式
1
|
等待时间 = 初试时间 * (倍数 ^ 重试次数) + 随机抖动
|
Go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
import "github.com/cenkalti/backoff/v4" // 截止 202507 已发布 v5
func Run(){
backOff := &backoff.ExponentialBackOff{
InitialInterval: backoff.DefaultInitialInterval, // 初始等待时间:500ms
RandomizationFactor: backoff.DefaultRandomizationFactor, // 随机因子:0.5
Multiplier: backoff.DefaultMultiplier, // 倍数:1.5
MaxInterval: 3 * time.Second, // 最大间隔:3秒
MaxElapsedTime: time.Duration(0), // 最大总时间:无限制
Stop: backoff.Stop, // 停止信号
Clock: backoff.SystemClock, // 时钟
}
operation := func() error {
// 业务逻辑
return nil
}
if err := backoff.Retry(operation, backOff);err!=nil{
return err
}
fmt.Println("连接成功")
}
|
有几个参数注意
backoff.Permanent(err)
返回不可 back 的错误
backoff.RetryAfter(seconds)
指定延迟多久后重试
最终执行的结果大概是这样
1
2
3
4
5
6
|
第1次重试: 500ms ± 250ms = 250ms ~ 750ms
第2次重试: 500ms × 1.5 = 750ms ± 375ms = 375ms ~ 1.125s
第3次重试: 750ms × 1.5 = 1.125s ± 562ms = 563ms ~ 1.687s
第4次重试: 1.125s × 1.5 = 1.687s ± 843ms = 844ms ~ 2.53s
第5次重试: 1.687s × 1.5 = 2.53s ± 1.265s = 1.265s ~ 3s
第6次重试: 达到最大间隔 3s,之后都是 3s ± 1.5s
|