写点什么

Content-Length 使用不规范导致 Socket Hang Up 问题

作者:Kevin Wu
  • 2022-12-27
    江苏
  • 本文字数:717 字

    阅读完需:约 2 分钟

Content-Length使用不规范导致Socket Hang Up问题

前言

XProxy 是基于 Node.js 研发的七层负载网关,承担着全公司所有互联网和私有云的流量入口,高峰期 QPS 达 20W,日志量每天达数十亿条,部署架构为两地三中心,网关机器集群接近三百台机器。


存在问题

业务方反馈,请求网关接口时出现超时未响应的情况,时而接收到 502 的状态码,错误信息为 Socket Hang Up。


排查过程

在业务方反馈问题后,首先查看网关的运行状态,看到网关的运行是正常的,并且仅仅是一个业务方反馈这个问题,其他业务方使用都是正常的,因此排除是网关应用问题。

接着继续排查网络问题,通过 tcping 发现业务方到网关的网络也是正常的,并且三次握手的时延也是比较低的,因此排除网络问题。

继续查看网关日志,从 Kibana 并没有看到接口正常转发到上游服务的日志,只看到接口的请求日志,并且日志记录了 Socket Hang Up 的 error,因此可以判断网关是接收到了请求,但是没有正常处理请求,那就只能抓包分析,通过抓包可以看到,该请求为 Get 请求,并且神奇的是请求头中竟然存在 Content-Length:


查阅rfc2616,可以清楚的了解到 Content-Length 是记录 body 的大小,一般用于服务端响应客户端时才会带上,作用是告诉客户端读完 Content-Length 字节大小的数据,数据也就传输完了,然而 Get 请求并没有 body,都是表单传输:


从 Github 上也搜索到类似的 issue:


为了更加准确地确定问题,在网关服务器上用相同的请求报文,带上 Content-Length 时问题是必现的,去掉 Content-Length 时就正常了。

带上 Content-Length 的请求:


不带 Content-Length 的请求:


解决方案

将问题反馈给业务方后,建议业务方检测代码使用的 HttpClient 是否正常,了解到当前 HttpClient 使用的是 Rest Templete,业务方确定 RestTemplete 有问题后,将 HttpClient 换成了 OkHttpClient,请求就恢复正常了。

用户头像

Kevin Wu

关注

To Be A Elegant Programmer 2018-01-29 加入

Golang、Node.js、中间件,目标是深入Rust

评论

发布
暂无评论
Content-Length使用不规范导致Socket Hang Up问题_TCP_Kevin Wu_InfoQ写作社区