近期刚接手一个兄弟公司项目,然后在之上开发了一些新功能,系统需要升级,之后测试就发现了一种很诡异的问题,http响应不定时出现延迟,且每次延迟之后返回504异常。在一步步排查之后,发现出现延迟的接口中,只有那些需要再次调用另一台内网服务器的接口时,才会出现,如下图。

这个问题出现时,还不是固定出现,一时半会很让人摸不着头脑,更诡异的是一旦出现超时,必定是60秒。。

首先分析504问题。出现504问题时,一定是第一个Nginx反向代理时,响应超时。所有的配置都是在nginx.conf里面设置的。

60秒让我想到了client_body_timeout这个参数,意义就是用于读取客户端请求体的超时时间。如果这个参数未配置,默认就是60s。因为权限缘故,阿里云上的NG配置我不能访问,但504错误可以认定是响应超时达到60秒。

其次,因为这个问题不是固定出现的,而是几次请求后出现的。后测试人员反馈,是同一个请求,第一次才会出现,后续又响应很迅速(1秒内)。这说明无论是A-web还是B-web,代码层面是没有问题的(系统没有做响应缓存)。

问题一定出在Nginx上!

我先检查A-web服务的日志,当我发起http请求之后,A-web的request内容接收几乎是瞬时的,因此延迟不可能发生在NGINX-1中

然后查看阿里云服务器上A-web调用内网服务器B-web服务后,获得响应的时间。查看后台日志后,诡异的一幕就出现了,60s的延迟果然反应在日志中。

60秒固定时间,一定是NGINX-2出了问题。但是在我在nginx官网上查阅了所有与时间有关的配置之后,并未发现除了client_body_timeout之外,有任何默认配置为60s的地方,内网服务器上,NGINX-2的keepalive_timeout 也被固定指定为65秒。

既然怀疑是NGXIN-2的问题,那我直接拿一个对外开放的端口,让A-web直连B-web测下不就清楚了吗?

果然,直连之后,这种诡异的60秒延迟消失了。。

既然觉得NGINX有问题,那看看日志不就行了。查看NGINX-2的日志,果然找到端倪了。。

upstream后面,被解析的请求地址居然变成了[::1],然后访问超时了。

查询相关资料,原来是我的proxy_pass地址配的localhost导致的。网上的解释是:localhost在部分windows下,优先会按照IPV6格式解析(这个主要是在host文件中中配置的),然后就变成了[::1]了。正好那台内网服务器是Window Server2008的。

如果按照上述说法,那么出现60秒超时,应该是先按照IPV6格式解析后,60秒无响应,再按IPV4解析,最后瞬间响应返回,但总时间已>60s。

最后,由于A-web到B-web的响应请求超过60s,所以A-web前面的NGXIN-1抛出了504异常。

将NGINX-2的proxy_pass配的localhost,改为127.0.0.1之后,该问题一样不再复现。

至于为什么第二次请求就不出现了,原因还是NGINX默认是有客户端缓冲区的,具体大小由client_header_buffer_size(默认1k)和client_body_buffer_size(32位上默认8k,64位上默认16k)控制的。

所以localhost这玩意,建议大家以后还是不要偷懒用了。开发可以,生产环境绝对不行!

 

 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐