Home  >  Article  >  Backend Development  >  How to implement a retry mechanism for specific requests using http.Transport in Go?

How to implement a retry mechanism for specific requests using http.Transport in Go?

王林
王林Original
2023-07-21 12:07:481607browse

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!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn