阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Nginx Proxy timeout排错

126次阅读
没有评论

共计 5755 个字符,预计需要花费 15 分钟才能阅读完成。

一、环境

当前的环境为 nginx 作为前端反向代理,upstream 为两台 tomcat。

二、原因

由于最近项目属于初期阶段,平日加班也比较多,刚好碰到一天没有什么问题的时间,我早早的收拾装备开心的坐上了地铁奔向家里。

此时,听着音乐的我快乐的坐在地铁上,突然音乐戛然而止,响起了来电的铃音。一种不好的预感油然而生,看来是有问题了。于是乎我拿出电话看到了我们老大的名字闪现在手机屏幕上,深呼一口气,接起电话。就听见我们老大说现在客户端那边报错等什么什么的。由于地铁里杂音很大,信号又不是太好,就没细问。反正就是服务器端有问题,我就先应答下来。此时的我还没有到家,于是就说到家了再看。于是老大就挂了电话。我就在心里回想到底说的是什么问题,可惜回忆了半天终还是没有听清说了什么。

三、排错

到家打开电脑,登上 QQ,就看到了群里 client 那边再反映的问题,截图显示部分请求服务端的资源出现了 request timed out 的现象。于是我就登陆到服务器端。首先查看各个进程是否正常。在确定正常之后,访问页面测试下也是正常的。由于客户端调用的是接口文件,浏览器没有办法直接测试访问,只能通过 nginx 的日志查看问题。

客户端那边测试的是 https 的协议,此时就查看 https 的部分日志:

2015/08/06 19:15:29 [error] 17709#0: *1380648 upstream timed out (110: Connection timed out) while sending request to upstream, client: xxx, server: www.xxxx.com, request: “POST /xxx/pub/xxx.do HTTP/1.1”, upstream: “http://xxxx:8082/xxx.do”, host: “www.xxxx.com:443”

2015/08/06 19:16:11 [error] 17709#0: *1380648 upstream timed out (110: Connection timed out) while sending request to upstream, client: xxx, server: www.xxxx.com, request: “POST /xxx/pub/xxx.do HTTP/1.1”, upstream: “http://xxxx:8082/xxx.do”, host: “www.xxxx.com:443”

 2015/08/06 19:17:29 [error] 17709#0: *1380648 upstream timed out (110: Connection timed out) while sending request to upstream, client: xxx, server: www.xxxx.com, request: “POST /xxx/pub/xxx.do HTTP/1.1”, upstream: “http://xxxx:8082/xxx.do”, host: “www.xxxx.com:443”

2015/08/06 19:29:29 [error] 17709#0: *1380648 upstream timed out (110: Connection timed out) while sending request to upstream, client: xxx, server: www.xxxx.com, request: “POST /xxx/pub/xxx.do HTTP/1.1”, upstream: “http://xxxx:8082/xxx.do”, host: “www.xxxx.com:443”

日志格式就类似上面的这些类容,看到这些,我就想到可能是 nginx 的 proxy 的一些超时时间的问题,于是就修改了 time out 的时间设置。

再次测试还是有此问题,我仔细想了一下,突然发现这边测试的是 https,而我修改的好像只是 http 的超时时间,于是再次修改,心里暗自激动的认为这下该 OK 了吧。没想到修改完之后,客户端那边测试还是一样的问题。此时就有些郁闷了。

由于我实时的再监控着后台日志,再次发现虽然报错,但是有些区别:

2015/08/06 19:47:31 [error] 17708#0: *1381368 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: xxx.xxx.xxx.xxx, server: www.xxx.com, request: “POST /xxx/xxx/xxxx.do HTTP/1.1”, upstream: “http://xxx.xxx.xxx:8082/xxx/home/xxx.do”, host: “

2015/08/06 19:50:11 [error] 12300#0: *1381368 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: xxx.xxx.xxx.xxx, server: www.xxx.com, request: “POST /xxx/xxx/xxxx.do HTTP/1.1”, upstream: “http://xxx.xxx.xxx:8082/xxx/home/xxx.do”, host: “www.xxx.com:443”

2015/08/06 19:55:04 [error] 132648#0: *1381368 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: xxx.xxx.xxx.xxx, server: www.xxx.com, request: “POST /xxx/xxx/xxxx.do HTTP/1.1”, upstream: “http://xxx.xxx.xxx:8082/xxx/home/xxx.do”, host: “www.xxx.com:443”

可以看到日志里面的错误码和报错信息发生了改变。按照这个提示,应该是 upstream 向 nginx 发送了重置的请求,这是为什么呢?

网上搜索了一下,发现大部分说的都还是 time out 的问题,有个别说是客户端 get 的头过大,但是明显这里用的是 POST 方法。那还是按照 time out 去查找问题看看,于是又想客户端那边咨询下是否设置了超时时长,客户端那边给的是设置了 10s 的超时时长。这样看来应该也不会有问题呀。10s 的情况下应该是足够服务器处理和响应了。

此时还没有想到问题在什么地方,只能多监控写日志看看,于是把 http 的访问日志和错误日志以及 https 的访问日志和错误日志都以 tail 的方式实时的监控着。就在这些日志监控当中,突然发现了几点奇怪的现象:

3.1、http 的错误日志也有 connection time out 的现象

2015/08/06 19:29:44 [error] 17708#0: *1380926 upstream timed out (110: Connection timed out) while reading response header from upstream, client: xxx.xxx.xxx.xxx, server: www.xxxx.com, request: “GET /xxx/xxx/xxx.png HTTP/1.1”, upstream: “http://xxx.xxx.xxx:8082/xxx/image/xxx.png”, host: “www.xxx.com”, referrer: “http://www.xxx.com/xxx/xxx/xxx.do?user_id=57&from=singlemessage&isappinstalled=1”

2015/08/06 19:29:44 [error] 17708#0: *1380930 upstream timed out (110: Connection timed out) while reading response header from upstream, client: xxx.xxx.xxx.xxx, server: www.xxx.com, request: “GET /xxx/xxx/xxx.png HTTP/1.1”, upstream: “http://xx.xxx.xxx.xxx:8082/xxx/xxx/xxx.png”, host: “www.xxx.com”, referrer: “http://www.xxx.com/xxx/xxx/xxx.do?user_id=57&from=singlemessage&isappinstalled=1”

3.2、https 访问日志和错误日志在同一时间点会出现两个请求

# 错误日志

2015/08/06 21:58:59 [error] 22498#0: *527 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: xxx.xxx.xxx.xxx, server: www.xxx.com, request: “POST /xxx/xxx/xxx.do HTTP/1.1”, upstream: “http://xxx.xxx.xxx.xxx:8082/xxx/xxx/xxx.do”, host: “www.xxx.com:443”

# 访问日志

xxx.xxx.xxx.xxx – – [06/Aug/2015:21:58:59 +0800] “POST /xxx/xxx/xxx.do HTTP/1.1” 200 1100 “-” “xxx/1.1.0 (iPhone Simulator; iOS 8.1; Scale/2.00)” “-“

上述可以看到在同一个时间点出现了两个请求,并且一个成功,一个失败,并且访问日志有很多 499 响应码的请求。而 499 响应码是说 /* 499, client has closed connection */. 就是说客户端主动关闭了连接,或者 nginx 两次提交 post 间隔过快也会出现此问题。

1、客户端主动关闭连接,是因为过了设置的超时时长就会关闭连接。这个又回到了 10s 的超时时长和频繁的发生 time out 现象的问题上了。

2、提交 POST 请求过快,nginx 会认为属于不安全的请求,便主动拒绝连接。这个有可能是客户端那边不间断的测试数据导致,对于这种情况,可以对 nginx 的配置文件进行配置以下参数来进行不主动关闭。

proxy_ignore_client_abort on;

但是这样配置是不安全的。此时为了解决问题,就怀着激动的心先配置测试下。

可悲的是配置了该参数,发现还是不能解决问题。心里落差再一次发生。不过没有关系,终究还是通过日志能发现各种问题的。

在确定排除了第二点的疑问后,回到第一点 (也就是 3.1 的问题上),为什么客户端那边测试的 https 的协议,在 http 协议里同样会出现该问题。这里的疑点重重呀。于是着重从这里下手。

客户端测试的接口文件是放在某个应用的目录下,虽然不能直接访问接口文件,但是可以访问其应用 web 目录。

通过访问 web 目录和结合日志发现了问题的所在:

1、nginx proxy 使用的是默认的轮询,所以每一次可能会调度到不同的后端服务器上。而此刻访问刷新页面时,其中一次会有些卡顿,看后台日志发现每次卡顿时都会出现一个报错。

2、出现报错的同时,正常的日志也会出现一次成功的请求。在看页面又出现了一次刷新。这就解释了之前同一个时间点出现两次请求的现象了。

3、此时在回头去看报错日志就很容易的看出问题所在了,发现所有的 error 都属于 upstream 中的同一台 tomcat。就说明是这台 tomcat 有问题。

在 nginx 中 down 掉这台 tomcat,客户端那边测试一切 OK。问题到此解决。至于为什么这台有问题,是白天开发直接动过 tomcat 的代码。问题只能白天上班来配合查找代码的问题。

四、总结

经过此次的排错,总结一下:

1、遇到问题要冷静处理,从最基础的开始排查。

2、善于利用各应用程序的日志进行错误跟踪。

3、还是要对各应用做到了然于心,对于各类报错尽量知道大概是什么问题。从哪里排查。

搞完问题,记录下来发现时间已经不早了,是该休息休息,为明天有更好的战斗状态!

更多 Nginx 相关教程见以下内容

CentOS 6.2 实战部署 Nginx+MySQL+PHP http://www.linuxidc.com/Linux/2013-09/90020.htm

使用 Nginx 搭建 WEB 服务器 http://www.linuxidc.com/Linux/2013-09/89768.htm

搭建基于 Linux6.3+Nginx1.2+PHP5+MySQL5.5 的 Web 服务器全过程 http://www.linuxidc.com/Linux/2013-09/89692.htm

CentOS 6.3 下 Nginx 性能调优 http://www.linuxidc.com/Linux/2013-09/89656.htm

CentOS 6.3 下配置 Nginx 加载 ngx_pagespeed 模块 http://www.linuxidc.com/Linux/2013-09/89657.htm

CentOS 6.4 安装配置 Nginx+Pcre+php-fpm http://www.linuxidc.com/Linux/2013-08/88984.htm

Nginx 安装配置使用详细笔记 http://www.linuxidc.com/Linux/2014-07/104499.htm

Nginx 日志过滤 使用 ngx_log_if 不记录特定日志 http://www.linuxidc.com/Linux/2014-07/104686.htm

Nginx 的详细介绍 :请点这里
Nginx 的下载地址 :请点这里

本文永久更新链接地址 :http://www.linuxidc.com/Linux/2015-08/121404.htm

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-20发表,共计5755字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中