系统环境
服务端:K8s集群使用Nginx Ingress Controller,并且支持http2
客户端:golang version 1.9.2,且使用http2
故障现象
Nginx偶发400 Bad Request,绝大部分请求正常返回200
故障排除步骤
(1)故障复现
使用golang http2 client,每个请求post相同的数据,直到response 400;查询nginx日志,response为400时,对应的request_length明显小
(2)开启nginx debug
本文使用的是Nginx Ingress Controller,开启debug的方式如图所示,修改deployment,增加参数“--v=5”,不过要注意,修改deployment后容器会重启,本文复现故障是在测试环境中。

根据response为400的时间,发现这样的info级别日志:client prematurely closed stream: only 0 out of 1125 bytes of request body received
即nginx收到的http header content-length是1125字节,但是http body里却是0字节
(3)查看客户端问题
打开客户端debug,env GODEBUG=http2debug=2 go test --timeout 30m -v test.go >> test.log 2>&1
debug日志中正常request信息如下图,而异常的request没有红线标识那行信息,即data并没有发出

(4)问题解决
按照https://github.com/golang/go/issues/25009的讨论,问题在于GOROOT目录下src/net/http/transport.go;修改之后GOROOT重新build,问题解决
这篇博客介绍了在K8s集群中使用Nginx Ingress Controller并支持http2时遇到的400 Bad Request错误。故障表现为Nginx偶发返回400,大部分请求正常。排查过程包括复现故障、开启Nginx Debug日志,发现客户端golang http2 client请求body缺失。通过开启客户端debug模式,发现请求数据未发出。最后,依据GitHub上的讨论,定位到golang源码问题并解决。
2万+

被折叠的 条评论
为什么被折叠?



