Nginx" upstream prematurely closed connection while reading response header from upstream"问题排查

问题背景

  咱们这边是一个基于Nginx的API网关(如下标记为A),最近两天有调用方反馈,偶尔会出现502错误,咱们从Nginx的error日志里看,就会发现有" upstream prematurely closed connection while reading response header from upstream"这么一条错误日志,翻译过来其实就是上游服务过早的关闭了链接,意思很清楚,可是为何会出现这种状况呢。并且是在业务低峰出现这种状况(也只是小几率的出现),在业务高峰的时候没有出现这种状况,并且上游服务方(如下标记为B)说出问题的请求他们那边没有收到,也就是没有任何记录,这就比较诡异了。测试环境不知道如何去复现,也就很差排查。nginx

排查过程

  一、在服务器上开启tcpdump抓包 tcpdump -nps0 -iany -w /tmp/20180617.pcap net [ip] and net [ip],若是不知道tcpdump怎么使用的同窗能够百度一下。服务器

  二、在nginx的error.log中观察到到有两条" upstream prematurely closed connection while reading response header from upstream"错误日志,分别是2018/06/07 20:41:27和2018/06/08 09:10:46两个时间点,以下图网络

  三、而后查看抓包数据,找到了对应时间点的包数据,从这个能够看出,A向B发送了一个1060-2143的包,,而服务端发送了一个Fin断开链接。为何服务端会断开链接了,咱们不得而知。并发

  四、上一步A发送包首字节数是1060,那必然前面确定发送过包,那咱们继续往上查,发现了以下图所示的现象。在20:40:22的时候3次握手创建链接并发送了第一个包;并且也查了在20:40:22到20:41:27中间这条长链接没有发送任何包tcp

  五、和B沟通,他们的Nginx中的keepalive_timeout配置为65秒,keepalive_timeout这个配置的意思是说长链接保持的时间,若是没有任何数据传输的话,超过这个时间,服务端会关闭这个链接。那这就对上了,说明在这65秒没有任何数据传输,也正好在这个点,A向B发送了数据,而B关闭了这个链接,因而就出现了上面的现象。测试

  六、固然这是我根据抓包分析出来的结果,我也本身模拟了这种状况,写了一个定时任务,每隔一分钟向第一台nginx发送请求,转发到第二台nginx上。第二台nginx的keepalive_timeout配置为60,在发送第七次的时候,出现了一样的问题,nginx打印一样的错误日志,抓包的结果也和上述状况一致。验证了我上述的分析过程。翻译

问题总结

  一、若是系统并发量不大,没有必要开启长链接,有两种方式,1、第一台nginx能够去除proxy_http_version 1.1; proxy_set_header Connection "0";这两个配置;2、第二台nginx的keepalive_timeout能够配置为0(默认是75)。日志

  二、上述问题个人解决方案是:暂时调大keepalive_timeout的值,先观察,但颇有可能仍是会有这个问题。blog

后记

  一、网络问题的排查过程是很痛苦了,再一次验证了基础知识的重要性。ip

  二、偶然报出的问题,必定不要忽视,说不定之后就是系统的瓶颈。

相关文章
相关标签/搜索