ホームページ  >  記事  >  バックエンド開発  >  Go で http.Transport を使用して特定のリクエストに対する再試行メカニズムを実装するにはどうすればよいですか?

Go で http.Transport を使用して特定のリクエストに対する再試行メカニズムを実装するにはどうすればよいですか?

王林
王林オリジナル
2023-07-21 12:07:481608ブラウズ

http.Transport を使用して Go で特定のリクエストの再試行メカニズムを実装するにはどうすればよいですか?

Web アプリケーションを開発する場合、ネットワーク リクエストが失敗することがよくあります。アプリケーションの堅牢性と安定性を向上させるために、特定のエラー コードが発生したときに自動的に再試行できます。 Go 言語では、http.Transport を通じて特定のリクエストの再試行メカニズムを実装できます。

まず、対応するパッケージをインポートする必要があります:

import (
    "fmt"
    "net/http"
    "time"
)

次に、カスタム トランスポートを作成し、その MaxIdleConnsPerHostMaxIdleConns を設定する必要があります。接続を再利用するためのプロパティ:

transport := &http.Transport{
    MaxIdleConnsPerHost: 10,
    MaxIdleConns:        100,
}

次に、HTTP リクエストを送信し、再試行ロジックを処理する関数を定義できます。この関数では、http.Client の Do メソッドを使用して HTTP リクエストを送信し、返されたエラー コードに基づいて再試行できます。

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("重试次数已达到上限")
}

再試行ロジックでは、次の 2 つを定義できます。補助関数 isRetryableError および isRetryableStatusCode は、再試行を実行する必要があるかどうかを決定するために使用されます。実際のニーズに応じて、どのエラー コードとステータス コードを再試行できるかを設定できます:

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
}

最後に、上記の関数を使用して HTTP リクエストを送信し、再試行できます:

func main() {
    resp, err := sendRequestWithRetry("http://example.com")
    if err != nil {
        fmt.Println("请求失败:", err)
    } else {
        fmt.Println("请求成功:", resp.Status)
        resp.Body.Close()
    }
}

上記のコード例 http.Transport を使用して、Go で特定のリクエストに対する再試行メカニズムを実装する方法を学びます。トランスポートをカスタマイズし、適切な再試行ロジックと組み合わせることで、アプリケーションがネットワーク要求の失敗をより適切に処理できるようになり、アプリケーションの信頼性と安定性が向上します。

以上がGo で http.Transport を使用して特定のリクエストに対する再試行メカニズムを実装するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。