问题背景

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

排查过程

  1、在服务器上开启tcpdump抓包 tcpdump -nps0 -iany -w /tmp/20180617.pcap net [ip] and net [ip],如果不知道tcpdump怎么使用的同学可以百度一下。

  2、在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两个时间点,如下图

  3、然后查看抓包数据,找到了对应时间点的包数据,从这个可以看出,A向B发送了一个1060-2143的包,,而服务端发送了一个Fin断开连接。为什么服务端会断开连接了,我们不得而知。

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

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

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

问题总结

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

  2、上述问题我的解决方案是:暂时调大keepalive_timeout的值,先观察,但很有可能还是会有这个问题。

后记

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

  2、偶然报出的问题,一定不要忽视,说不定以后就是系统的瓶颈。

Nginx" upstream prematurely closed connection while reading response header from upstream"问题排查的更多相关文章

  1. nginx error: upstream prematurely closed connection while reading response header from upstream

    本篇文章由:http://xinpure.com/nginx-error-upstream-prematurely-closed-connection-while-reading-response-h ...

  2. upstream prematurely closed connection while reading response header from upstream

    upstream prematurely closed connection while reading response header from upstream nginx配置uwsgi的时候  ...

  3. 解决flask的502错误:upstream prematurely closed connection while reading response header from upstream

    我在使用 tiangolo/uwsgi-nginx-flask 部署flask应用的时候,经常运行一会儿就出现502错误,重新启动容器后,就恢复. 且经常会出现数据更新后,刷新结果不一致. docke ...

  4. nginx 超时问题: upstream timed out (110: Connection timed out) while reading response header from upstream

    目录 错误内容 错误原因 错误解决办法 错误内容 我们可以在error.log 里面可以看到 错误内容:upstream timed out (110: Connection timed out) w ...

  5. nginx recv() failed (104: Connection reset by peer) while reading response header from upstream解决方法

    首先说下 先看 按照ab 每秒请求的结果 看看 都有每秒能请求几个 如果并发量超出你请求的个数 会这样 所以一般图片和代码服务器最好分开 还有看看io瓶ding 和有没有延迟的PHP代码执行 0 先修 ...

  6. recv() failed (104: Connection reset by peer) while reading response header from upstream

    2017年12月1日10:18:34 情景描述: 浏览器执行了一会儿, 报500错误 运行环境:  nginx + php-fpm nginx日志:  recv() failed (104: Conn ...

  7. upstream timed out (110: Connection timed out) while reading response header from upstream

    Nginx报错日志有如下内容: upstream timed out (110: Connection timed out) while reading response header from up ...

  8. xdebug 一直报错 upstream timed out (110: Connection timed out) while reading response header from upstream

    本地主机(Windows环境192.168.66.1)访问虚拟机(192.168.66.139)里面的搭建的php环境(系统centos6.5版本,php版本是5.5.30 ,xdebug 2.4.0 ...

  9. upstream timed out (110: Connection timed out) while reading response header from upstream, client:

    遇到的问题 之前没配置下面这段,访问时候偶尔会出现 504 gateway timeout,由于偶尔出现,所以不太好排查 proxy_connect_timeout 300s;proxy_read_t ...

随机推荐

  1. Phoenix批量修改数据

    很简单的一个东西,查了挺久的,浪费了很多的时间 直接用Upsert Into Select就可以了 例:把tables表中cloumn2列等于bbb的都改成aaa Upsert Into Table  ...

  2. 生成RSA2公钥、私钥

    RSA2是一种被使用广泛的非对称加密算法. openssl OpenSSL> genrsa -out app_private_key.pem # 私钥RSA2 OpenSSL> rsa - ...

  3. linux命令(43):cal命令

    cal命令可以用来显示公历(阳历)日历.公历是现在国际通用的历法,又称格列历,通称阳历.“阳历”又名“太阳历”,系以地球绕行太阳一周为一年,为西方各国所通用,故又名“西历”. 1.命令格式: cal  ...

  4. 封装ajax方法

    function ajaxRequest(type, url, data, callback, loading, cache) { var ajaxConfig = { url: '', data: ...

  5. mysql:视图、触发器、事务、存储、函数、流程控制

    阅读目录 一 视图 二 触发器 三 事务 四 存储过程 五 函数 六 流程控制 回到顶部 一 视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只 ...

  6. python中global变量释疑

    疑问 为什么main中不能写global x语句? 在函数中如何修改global变量? 在main中修改了global变量后,在子进程中为什么没有效果? 如何利用进程池的initializer参数(函 ...

  7. Mysql 中的Text字段的范围

    mysql中text 最大长度为65,535(2的16次方–1)字符的TEXT列.如果你觉得text长度不够,可以选择 MEDIUMTEXT最大长度为16,777,215. LONGTEXT最大长度为 ...

  8. AC日记——[Sdoi2010]粟粟的书架 bzoj 1926

    1926 思路: 主席树+二分水题: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 500005 #defi ...

  9. Ext 目录

    adapter:负责将里面提供第三方底层库(包括Ext自带的底层库)映射为Ext所支持的底层库. build: 压缩后的ext全部源码(里面分类存放). docs: API帮助文档. exmaples ...

  10. C# CreateProcess的测试

    很奇怪的一个现象,在C#中使用Process来启动进程,启动文件名必须是系统指定的扩展名.EXE,而我使用原生的Win32API ::CreateProcess ()并没有这个限制,以后遇到类似的问题 ...