How to use http.Transport to implement a retry mechanism for specific requests in Go?
When developing web applications, network requests often fail. To improve the robustness and stability of your application, you can automatically retry when specific error codes are encountered. In the Go language, the retry mechanism for specific requests can be implemented through http.Transport.
First, we need to import the corresponding package:
import ( "fmt" "net/http" "time" )
Next, we need to create a custom Transport and set its MaxIdleConnsPerHost
and MaxIdleConns
Properties to reuse the connection:
transport := &http.Transport{ MaxIdleConnsPerHost: 10, MaxIdleConns: 100, }
Then we can define a function that sends the HTTP request and handles the retry logic. In this function, we can use the Do method of http.Client
to send an HTTP request and retry based on the returned error code:
func sendRequestWithRetry(url string) (*http.Response, error) { client := &http.Client{ Transport: transport, } for i := 0; i < 3; i++ { // 最多重试3次 resp, err := client.Get(url) if err != nil { if isRetryableError(err) { fmt.Printf("请求失败,正在进行第 %d 次重试... ", i+1) time.Sleep(1 * time.Second) continue } return nil, err } if resp.StatusCode == http.StatusOK { return resp, nil } resp.Body.Close() if isRetryableStatusCode(resp.StatusCode) { fmt.Printf("请求失败,正在进行第 %d 次重试... ", i+1) time.Sleep(1 * time.Second) continue } return nil, fmt.Errorf("请求失败,错误码:%d", resp.StatusCode) } return nil, fmt.Errorf("重试次数已达到上限") }
In the retry logic, we can define Two auxiliary functions isRetryableError
and isRetryableStatusCode
are used to determine whether a retry should be performed. According to actual needs, we can set which error codes and status codes can be retried:
func isRetryableError(err error) bool { // 判断是否为连接错误等常见错误 // 可根据实际需求进行修改 if err == io.EOF || strings.Contains(err.Error(), "connection reset by peer") || strings.Contains(err.Error(), "no such host") { return true } return false } func isRetryableStatusCode(code int) bool { // 判断是否为可重试的HTTP状态码 // 可根据实际需求进行修改 if code >= 500 || code == http.StatusBadGateway || code == http.StatusServiceUnavailable { return true } return false }
Finally, we can use the above function to send HTTP requests and retry:
func main() { resp, err := sendRequestWithRetry("http://example.com") if err != nil { fmt.Println("请求失败:", err) } else { fmt.Println("请求成功:", resp.Status) resp.Body.Close() } }
The above code example Learn how to use http.Transport to implement a retry mechanism for specific requests in Go. By customizing the Transport and combining it with appropriate retry logic, we can enable the application to better handle the failure of network requests and improve the reliability and stability of the application.
The above is the detailed content of How to implement a retry mechanism for specific requests using http.Transport in Go?. For more information, please follow other related articles on the PHP Chinese website!