指数退避算法

指数退避算法是一种网络错误处理策略,用于在客户端重试失败的请求时,增加每次重试之间的延迟时间。这种算法旨在避免连续的请求冲突,并提高网络资源的利用率。

当客户端在网络请求失败后,不是立即重试,而是等待一段固定的时间间隔后再进行重试。这个时间间隔会随着重试次数的增加而呈指数级增长。例如,第一次重试可能等待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
本文阅读量 次, 总访问量 ,总访客数
Built with Hugo .   Theme Stack designed by Jimmy