Maison  >  Article  >  développement back-end  >  Comment implémenter un mécanisme de nouvelle tentative pour des requêtes spécifiques à l'aide de http.Transport in Go ?

Comment implémenter un mécanisme de nouvelle tentative pour des requêtes spécifiques à l'aide de http.Transport in Go ?

王林
王林original
2023-07-21 12:07:481608parcourir

Comment utiliser http.Transport pour implémenter un mécanisme de nouvelle tentative pour des requêtes spécifiques dans Go ?

Lors du développement d'applications Web, des échecs de requêtes réseau sont souvent rencontrés. Pour améliorer la robustesse et la stabilité de votre application, vous pouvez réessayer automatiquement lorsque des codes d'erreur spécifiques sont rencontrés. Dans le langage Go, le mécanisme de nouvelle tentative pour des requêtes spécifiques peut être implémenté via http.Transport.

Tout d'abord, nous devons importer le package correspondant :

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

Ensuite, nous devons créer un transport personnalisé et définir ses propriétés MaxIdleConnsPerHost et MaxIdleConns pour une réutilisation de la connexion : 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("重试次数已达到上限")
}

在重试逻辑中,我们可以定义两个辅助函数isRetryableErrorisRetryableStatusCode

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
}

Nous pouvons ensuite définir une fonction qui envoie la requête HTTP et gère la logique de nouvelle tentative. Dans cette fonction, nous pouvons utiliser la méthode Do de http.Client pour envoyer une requête HTTP et réessayer en fonction du code d'erreur renvoyé :

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

Dans la logique de nouvelle tentative, nous pouvons définir deux fonctions auxiliaires isRetryableError et isRetryableStatusCode sont utilisés pour déterminer si une nouvelle tentative doit être effectuée. En fonction des besoins réels, nous pouvons définir quels codes d'erreur et codes d'état peuvent être réessayés :

rrreee

Enfin, nous pouvons utiliser la fonction ci-dessus pour envoyer des requêtes HTTP et réessayer : 🎜rrreee🎜L'exemple de code ci-dessus montre comment utiliser http dans Go . Transport implémente un mécanisme de nouvelle tentative pour des requêtes spécifiques. En personnalisant le transport et en le combinant avec une logique de nouvelle tentative appropriée, nous pouvons permettre à l'application de mieux gérer l'échec des requêtes réseau et d'améliorer la fiabilité et la stabilité de l'application. 🎜

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn