使用retry-go给项目添加重试机制
文章发布较早,内容可能过时,阅读注意甄别。
# 前言
在编写分布式应用程序时,有时会出现一些短暂的错误,例如网络问题、服务端连接中断等。这些错误可能会导致函数执行失败,但在稍后重新尝试时可能会成功。在这种情况下,我们可以使用重试机制。
retry-go 是一个轻量级的 Golang 库,它使重试代码块变得更加简单。它通过提供一个简单的 API 来实现这一点,这使得开发人员可以在代码中轻松地添加重试逻辑。
- name: retry-go
desc: 一个提供 retry 能力的 go 库
avatar: https://avatars2.githubusercontent.com/u/416130?s=460&u=8753e86600e300a9811cdc539aa158deec2e2724&v=4
link: https://github.com/avast/retry-go
bgColor: "#ffa8a8"
1
2
3
4
5
2
3
4
5
# 安装
使用 go get
命令安装 retry-go:
go get github.com/avast/retry-go
1
# 使用
以下是一个使用 retry-go 进行网络重试的示例:
package main
import (
"fmt"
"net/http"
"time"
"github.com/avast/retry-go"
)
func main() {
err := retry.Do(
func() error {
_, err := http.Get("http://example.com")
return err
},
retry.Delay(time.Second),
retry.Attempts(3),
retry.DelayType(retry.FixedDelay),
)
if err != nil {
fmt.Println("请求失败:", err)
} else {
fmt.Println("请求成功")
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
在这个例子中,我们使用了http.Get
函数来执行 GET 请求。如果请求失败,我们使用 retry-go 重试三次。retry-go 将等待一秒钟,然后再次尝试请求。如果请求成功,代码将继续执行。如果请求仍然失败,它将返回最后一个错误。
# 实际案例
以下通过一个实际案例做一个功能使用上的展示:
package main
import (
"errors"
"fmt"
"math/rand"
"time"
"github.com/avast/retry-go"
)
func main() {
var num int
var err error
// 定义一个重试策略
retryStrategy := []retry.Option{
retry.Delay(100 * time.Millisecond),
retry.Attempts(5),
retry.LastErrorOnly(true),
}
// 使用重试策略进行重试
err = retry.Do(
func() error {
num, err = CheckNum()
if err != nil {
return err
}
return nil
},
retryStrategy...)
if err != nil {
fmt.Println("Error occurred after 5 retries")
} else {
fmt.Println(num)
}
}
// 生成一个随机数,如果小于50,则返回错误,如果大于50,则返回这个数
func CheckNum() (num int, err error) {
fmt.Println("start check number")
rand.Seed(time.Now().UnixNano())
num = rand.Intn(100)
if num < 50 {
fmt.Println(num)
return 0, errors.New("test error")
} else {
return
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
这个示例是可以直接套用在实际项目当中的,将重试策略分离,然后解决对应函数方法出现的异常问题。
函数执行之后,可以看到输出如下:
$ go run main.go
start check number
32
start check number
43
start check number
69
1
2
3
4
5
6
7
2
3
4
5
6
7
关于 option
配置项,这里做一下简单解析:
当使用 retry-go
库时,你可以定义一个重试策略,以决定何时进行重试,以及如何进行重试。以下是一些可以在重试策略中配置的选项:
retry.Delay(delay time.Duration)
:设置重试之间的延迟时间。可以使用time.Duration
类型的值,例如10 * time.Millisecond
。retry.DelayType(delayType retry.DelayType)
:设置重试延迟的类型。可以是retry.FixedDelay
(等待固定的延迟时间)或retry.BackOffDelay
(在每次重试之后加倍延迟时间)。retry.MaxJitter(maxJitter time.Duration)
:设置重试延迟的最大抖动时间。可以使用time.Duration
类型的值,例如2 * time.Millisecond
。默认为0
。retry.MaxDelay(maxDelay time.Duration)
:设置重试延迟的最大时间。可以使用time.Duration
类型的值,例如5 * time.Second
。默认为0
,表示没有限制。retry.Attempts(attempts uint)
:设置重试次数的最大值。默认为0
,表示没有限制。retry.RetryIf(retryIfFunc retry.RetryIfFunc)
:设置一个函数,用于确定是否应该重试。该函数接收一个error
类型的参数,并返回一个布尔值,表示是否应该重试。默认为nil
,表示始终重试。retry.LastErrorOnly(lastErrorOnly bool)
:设置是否只记录最后一次错误。如果设置为true
,则只记录最后一次错误,否则记录所有错误。默认为false
。retry.OnRetry(onRetryFunc retry.OnRetryFunc)
:设置一个函数,在每次重试之前调用。该函数接收一个uint
类型的参数,表示已经重试的次数。默认为nil
。
# 最后
retry-go 是一个简单易用的重试库,它可以帮助开发人员轻松地添加重试逻辑。它提供了强大的功能,在一些场景当中,你可以考虑使用。
最后的最后:
本文由 GPT 辅助编写,感谢 GPT,以后技术类的文章,可能会经常与之合作。
上次更新: 2024/11/19, 23:11:42