Retry-Go:Go 優雅重試
在 Go 語言的開發過程中,我們經常需要執行可能失敗的操作,比如網絡請求。如果每次失敗都直接報錯並終止程序,用戶體驗就會很差。通常的做法是重試,即在失敗後等待一段時間再嘗試重新執行。
retry-go (github.com/avast/retry-go) 是一個輕量級的 Go 語言重試庫,提供簡單易用的**「重試機制」**,支持:
-
自定義重試策略(固定間隔、指數回退、隨機回退)。
-
最大重試次數(避免無限重試)。
-
上下文控制(超時或手動取消)。
-
自定義錯誤處理(僅對特定錯誤進行重試)。
安裝
go get github.com/avast/retry-go/v4
基本使用
以下示例展示瞭如何使用 retry-go 進行 HTTP 請求的自動重試:
url := "http://example.com"
var body []byte
err := retry.Do(
func() error {
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
body, err = io.ReadAll(resp.Body)
if err != nil {
return err
}
return nil
},
)
if err != nil {
// 處理錯誤
}
fmt.Println(string(body))
帶返回數據的重試:
url := "http://example.com"
body, err := retry.DoWithData(
func() ([]byte, error) {
resp, err := http.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return body, nil
},
)
if err != nil {
// 處理錯誤
}
fmt.Println(string(body))
默認重試策略
閱讀源碼後,我們可以看到默認配置:
attempts: uint(10), // 默認最多重試 10 次
delay: 100 * time.Millisecond, // 初始基礎間隔 100ms
maxJitter: 100 * time.Millisecond, // 最大抖動 100ms
delayType: CombineDelay(BackOffDelay, RandomDelay), // 指數退避 + 隨機抖動
默認的設置不是固定間隔的重試,而是:指數退避增長(BackOffDelay)加上一個 0~100ms 的隨機抖動(RandomDelay)。默認最多重試 10 次。
最大重試次數
retry.Do(
task,
retry.Attempts(5), // 最大重試 5 次
)
如果設置成 retry.Attempts(0),無限重試,直到成功。
重試間隔
retry.Do(
task,
retry.Delay(200*time.Millisecond), // 每次重試間隔 200 毫秒
)
指數回退
retry.Do(
task,
retry.DelayType(retry.BackOffDelay), // 指數回退策略
)
隨機延遲
retry.Do(
task,
retry.DelayType(retry.RandomDelay), // 隨機回退策略
)
固定延遲
retry.Do(
task,
retry.DelayType(retry.FixedDelay),
)
超時控制
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
retry.Do(
task,
retry.Context(ctx),
)
僅在特定錯誤時重試
當返回的錯誤值等於 retry.RetryIf() 中定義的條件時才進行重試。
retry.Do(
func() error {
return errors.New("special error")
},
retry.RetryIf(func(err error) bool {
return err.Error() == "special error"
}),
)
僅在特定錯誤時終止重試
當使用 retry.Unrecoverable() 包裹錯誤值後,返回這個錯誤時不會再進行重試。
retry.Do(
func() error {
return retry.Unrecoverable(errors.New("special error"))
},
)
References
https://github.com/avast/retry-go
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/zehApJEFjm5CZB_RqOJF6A