为了账号安全,请及时绑定邮箱和手机立即绑定

是否有必要读取并关闭响应主体以重试 TCP 连接?

是否有必要读取并关闭响应主体以重试 TCP 连接?

Go
慕的地6264312 2022-06-21 16:27:47
我正在使用http.RoundTripperGo 实现重试。这是一个实现示例。type retryableRoundTripper struct {    tr            http.RoundTripper    maxRetryCount int}func (t *retryableRoundTripper) RoundTrip(req *http.Request) (resp *http.Response, err error) {    for count := 0; count < t.maxRetryCount; count++ {        log.Printf("retryableRoundTripper retry: %d\n", count+1)        resp, err = t.tr.RoundTrip(req)        if err != nil || resp.StatusCode != http.StatusTooManyRequests {            return resp, err        }    }    return resp, err}问题是否有必要读取并关闭响应主体以重试 TCP 连接?func (t *retryableRoundTripper) RoundTrip(req *http.Request) (resp *http.Response, err error) {    for count := 0; count < t.maxRetryCount; count++ {        log.Printf("retryableRoundTripper retry: %d\n", count+1)        resp, err = t.tr.RoundTrip(req)        if err != nil || resp.StatusCode != http.StatusTooManyRequests {            return resp, err        }    }    // add    io.Copy(ioutil.Discard, resp.Body)    resp.Body.Close()    return resp, err}作为旁注,我编写了一个测试并确认重试按预期工作。(在 Go Playground 中,它超时,但它在本地工作。)https://play.golang.org/p/08YWV0kjaKr
查看完整描述

1 回答

?
慕少森

TA贡献2019条经验 获得超9个赞

当然,您需要阅读连接以确保它可以重复使用,并且需要按照文档说明关闭连接。

如文档中所述:

客户端完成后必须关闭响应正文

如果正文未读完并关闭,则默认 HTTP 客户端的传输可能不会重用 HTTP/1.x “保持活动” TCP 连接。

如果服务器想要发送的数据超出初始读取缓冲区的容量,它将被阻止发送响应。这意味着如果传输尝试通过该连接发送新请求,服务器可能无法处理它,因为它从未完成第一个请求。这通常会导致客户端错误connection reset by peer和服务器错误write: broken pipe

如果您想尝试重用连接,但限制读取量,请使用io.LimitedReader和/或检查ContentLength值。这样,当处理错误和建立新连接比读取无限量的数据更快时,您可以丢弃连接。请参阅限制在响应 HTTP GET 请求中读取的数据量


查看完整回答
反对 回复 2022-06-21
  • 1 回答
  • 0 关注
  • 93 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号