# 重试策略
重试作为一个常见的可用性保障手段,我们会经常用到。但是在重试的时候,控制重试次数、重试间隔等逻辑差不多,所以我们统一抽象出来了 retry 包,提供了一致性的接口:
type Strategy interface {
// Next 返回下一次重试的间隔,如果不需要继续重试,那么第二参数返回 false
Next() (time.Duration, bool)
}
1
2
3
4
2
3
4
我们提供了两个实现:
- 等间隔重试
- 指数退避重试
# 等间隔重试
等间隔重试有两个参数:
- 重试间隔
- 最大重试次数
例如:
func ExampleFixedIntervalRetryStrategy_Next() {
retry, err := NewFixedIntervalRetryStrategy(time.Second, 3)
if err != nil {
fmt.Println(err)
return
}
interval, ok := retry.Next()
for ok {
fmt.Println(interval)
interval, ok = retry.Next()
}
// Output:
// 1s
// 1s
// 1s
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
可以看到,连续输出了三次间隔 1s。
# 指数退避重试
指数退避重试有三个重要的参数:
- 初始间隔
- 最大重试间隔
- 最大重试次数
该重试机制是第一次按照初始间隔进行重试,后续每一次调用 Next 返回的间隔都是按照两倍来增长,直到触及最大重试间隔。当达到最大重试次数之后,再调用 Next 就会返回 false。
例如:
func ExampleExponential() {
retry, err := NewExponentialBackoffRetryStrategy(time.Second, time.Second * 5, 10)
if err != nil {
fmt.Println(err)
return
}
interval, ok := retry.Next()
for ok {
fmt.Println(interval)
interval, ok = retry.Next()
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
那么最终输出的结果是1s,2s,4s,5s,5s,5s,5s,5s,5s,5s
。
← 协程池