请求超时的 http 重试 (408)

Posted

技术标签:

【中文标题】请求超时的 http 重试 (408)【英文标题】:http retry for Request Timeout (408) 【发布时间】:2021-10-08 16:29:48 【问题描述】:

使用 hashcorp go-retryablehttp 库 (https://github.com/hashicorp/go-retryablehttp)

它会自动重试所有5xx 代码:

retryablehttp 在特定条件下执行自动重试。主要是,如果客户端返回错误(连接错误等),或者如果收到500范围的响应码(501除外),则在等待一段时间后调用重试。否则,返回响应并留给调用者解释。

是否有可能在Request Timeout 上重试,例如在408 http 状态码上只是 ootb? 或者我应该构建一些自定义包装器?

【问题讨论】:

【参考方案1】:

您可以实现自己的重试策略并将其传递给 Client.CheckRetry 字段。

文档参考:

https://pkg.go.dev/github.com/hashicorp/go-retryablehttp?utm_source=godoc#Client https://pkg.go.dev/github.com/hashicorp/go-retryablehttp?utm_source=godoc#DefaultRetryPolicy

代码参考:

https://github.com/hashicorp/go-retryablehttp/blob/02c1586c8f14be23e7eeb522f1094afbabf45e93/client.go#L401 https://github.com/hashicorp/go-retryablehttp/blob/02c1586c8f14be23e7eeb522f1094afbabf45e93/client.go#L424

代码可能类似于

package main

import (
    "context"
    "net/http"

    "github.com/hashicorp/go-retryablehttp"
)

func main() 

    retryClient := retryablehttp.NewClient()
    retryClient.RetryMax = 10
    retryClient.CheckRetry = func(ctx context.Context, resp *http.Response, err error) (bool, error) 
        ok, e := retryablehttp.DefaultRetryPolicy(ctx, resp, err)
        if !ok && resp.StatusCode == http.StatusRequestTimeout 
            return true, nil 
            // return true for a retry, 
            // if e is nil,
            // you might want to populate that error 
            // to propagate it.
            // see https://github.com/hashicorp/go-retryablehttp/blob/02c1586c8f14be23e7eeb522f1094afbabf45e93/client.go#L673
        
        return ok, e
    

【讨论】:

【参考方案2】:

由于源代码在文件client.go 的第354 行中指定,您可以配置CheckRetry 函数以在任何自定义场景中重试。

    // CheckRetry specifies the policy for handling retries, and is called
    // after each request. The default policy is DefaultRetryPolicy.
    CheckRetry CheckRetry

您只需编写以下类型的函数并使用该自定义实现配置retryablehttp.Client.CheckRetry

type CheckRetry func(ctx context.Context, resp *http.Response, err error) (bool, error)

【讨论】:

以上是关于请求超时的 http 重试 (408)的主要内容,如果未能解决你的问题,请参考以下文章

OPENSSL s_cient 请求失败(408 请求超时)

使用 PHP 了解 Apache 上的“408 请求超时”

SpringCloud Fegin超时重试源码

如何调试特定 SQL 偶尔会导致 BigQuery “请求超时。请重试”

Spring Cloud Feign 重试机制-如何实现请求重试

Nacos Config连接超时重试