http 2:服务器发送GOAWAY并关闭连接; LastStreamID=1999

hrysbysz  于 12个月前  发布在  Go
关注(0)|答案(3)|浏览(458)

我有一个for循环,在这个循环中,我调用了从osrm服务器获取响应的函数,一段时间后ioutil.ReadAll(resp.Body)返回err,打印http2: server sent GOAWAY and closed the connection; LastStreamID=1999, ErrCode=NO_ERROR, debug=""

func RequestGET(req string) []byte {

    reqst, err := http.NewRequest("GET", req, nil)
    client := &http.Client{}
    resp, err := client.Do(reqst)
    if err != nil {
        panic(err)
    }
    resp_data, err := ioutil.ReadAll(resp.Body)
    resp.Body.Close()
    if err != nil {
        fmt.Println(err)
    }
    return resp_data
}

Isn't resp.Body.Close()关闭连接?我希望每次都能得到一个新的。

nlejzf6q

nlejzf6q1#

服务器由于某种原因正在关闭连接;后端关闭、超时等。除了重试,您没有什么可以做的,就像您遇到任何其他连接错误一样。在一个相关的问题(https://golang.org/issue/18639)中有一些关于自动重试的讨论,但它通常看起来像客户端正在按预期工作。
Response.Body.Close不会关闭连接,否则它将破坏http1.1和http 2使用持久连接的目的。阅读和关闭响应体是您允许HTTP客户端重用连接的方式。

icnyk63a

icnyk63a2#

我遇到了一个与GET请求有关的问题,该请求发送了一个超过50k的报头。默认情况下,nginx的限制是4k。因此,如果您的服务器因为请求头而断开连接,您可以收到此消息。

hc8w905p

hc8w905p3#

以下是我从https://github.com/golang/go/issues/18639#issuecomment-1071940233得到的简短结论
讨论
@CameronGo如果对其他人有帮助的话,我们通过更改ALB配置来解决这个问题,使用HTTP 1而不是HTTP 2。这显然是一种变通方法,而不是修复,但它现在是有效的,直到Go改变这种行为。
@bradfitz贡献者bradfitz于2022年3月18日发表评论,但它现在是有效的,直到Go改变这种行为。
你误解了问题所在。看我之前的评论。这不是围棋能解决的问题ALB在响应中间挂断。这是亚马逊的问题。
这是一个关于Go如何在http2.0连接下处理aws负载均衡器(或其他)行为的问题
https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-troubleshooting.html
负载均衡器发送响应代码000对于HTTP/2连接,如果任何报头的压缩长度超过8 K字节,或者通过一个连接服务的请求数超过10,000,负载均衡器将发送GOAWAY帧并使用TCP FIN关闭连接
所以根本原因=>是“heavy header”或“ddos”(高负载)到服务器/服务,你的Go应用程序在那里做http2.0请求
我建议你

  • 增加Go应用处理http请求时应用/服务的吞吐量
  • 在Go应用程序中处理此错误并返回503忙碌http代码(如果您的Go应用程序是http微服务,或者在超时后重试)
  • 增加对此类情况的监控

相关问题