所以我在 Golang 中有一个 grpc 服务,我想在它上面暴露一个 HTTP API,所以我在服务中添加了 grpc-gateway。
当我尝试向我的服务发出 HTTP 请求时,它失败并出现一个奇怪的错误 500 Internal Server Error caused by: stream error: stream ID 19; PROTOCOL_ERROR
这发生在负载均衡器将请求转发到 http 端口(运行 grpc-gateway 的端口)之后
它是一个不稳定的错误,大多数时候请求都会失败,但有时请求会毫无错误地通过
查看浏览器中的请求,我看到当从前端发送请求时,它会添加此标头TE: trailers
,并根据此线程上的 评论https://github.com/golang/go/issues/29125#issuecomment-676831990 TE 标头会导致此问题。因此,我尝试使用 traefik 中间件删除 TE 标头,但即使这样也没有解决问题,即使在标头到达 http 端口之前删除了标头,请求仍然失败并出现相同的错误。
然后我打开GODEBUG=http2debug=2
并在日志中找到了这个
http2: Framer 0xc000272e00: read HEADERS flags=END_HEADERS stream=5 len=29
http2: decoded hpack field header field ":authority" = "dev-env.something.com"
http2: decoded hpack field header field ":method" = "POST"
http2: decoded hpack field header field ":path" = "/v1/someAPI/Create"
http2: decoded hpack field header field ":scheme" = "http"
http2: decoded hpack field header field "x-forwarded-host" = "dev-env.something.com"
http2: decoded hpack field header field "x-forwarded-port" = "443"
http2: decoded hpack field header field "sec-fetch-dest" = "empty"
http2: decoded hpack field header field "x-forwarded-for" = "XX.XXX.XXX.X"
http2: decoded hpack field header field "sec-fetch-mode" = "cors"
http2: decoded hpack field header field "accept" = "application/json, text/plain, */*"
http2: decoded hpack field header field "te" = "trailers"
http2: decoded hpack field header field "x-real-ip" = "XX.XXX.XXX.X"
http2: decoded hpack field header field "user-agent" = "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0"
http2: decoded hpack field header field "accept-encoding" = "gzip, deflate, br"
http2: decoded hpack field header field "sec-fetch-site" = "same-origin"
http2: decoded hpack field header field "referer" = "https://dev-env.something.com/"
http2: decoded hpack field header field "x-forwarded-proto" = "https"
http2: decoded hpack field header field "accept-language" = "en-US,en;q=0.5"
http2: decoded hpack field header field "x-forwarded-server" = "traefik-xxxxxxxxxxx"
http2: decoded hpack field header field "origin" = "https://dev-env.something.com"
http2: decoded hpack field header field "content-type" = "application/json"
http2: decoded hpack field header field "content-length" = "12"
http2: Framer 0xc000272e00: read DATA flags=END_STREAM stream=3 len=12 data="{\"name\":\"test\"}"
http2: Framer 0xc000272e00: wrote RST_STREAM stream=3 len=4 ErrCode=PROTOCOL_ERROR
http2: Framer 0xc000272e00: wrote WINDOW_UPDATE len=4 (conn) incr=12
http2: Framer 0xc000272e00: wrote PING len=8 ping="\x02\x04\x10\x10\t\x0e\a\a"
http2: Framer 0xc000272e00: read SETTINGS flags=ACK len=0
http2: Framer 0xc000272e00: read PING flags=ACK len=8 ping="\x02\x04\x10\x10\t\x0e\a\a"
现在,即使是日志也不是很有帮助,或者我不知道如何阅读它们,而且我遗漏了一些明显的东西
curl 请求的形式为curl -X POST -H "Content-Type: application/json" "https://domain.name.com/v1/someAPI/Create" -d "{\"name\": \"test\" }"
有人可以告诉我出了什么问题,这是 stdlib 中的错误吗?如果不是,如果有人能告诉我如何阅读 http2 日志或在标准库中查找这些日志的来源,那仍然会有很大帮助