首页
学习
活动
专区
工具
TVP
发布

一条502报警引发的胡思乱想

安心倒计时

忙完了今天的工作, 终于到了周五,可以好好休息下了。

睡梦惊醒

就在安心养神的时候, 同事转给了我一条nginx 502的报警, 赶紧去线上一顿排查。

首先得先找出哪台机器报出的(同时喊运维看下线上负载情况), 发现01机器的nginx日志在报警时间点的错误信息:

*272881176 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: xx.xx.xx.xx, server: , request: "POST /xxx/xxx HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host:

"xx.xx.xx.xx:8081"

recv()为接收返回数据的系统函数,基本可以先认为报错原因为

Nginx发现某服务与自己通信的连接断掉了,就会返回给客户端502错误。

那么nginx是从哪里接收数据呢,报错信息同样很明显,fastcgi://127.0.0.1:9000

思考缘由

同样思考为什么php的处理进程会中断呢?

莫非执行任务超时,fpm主动杀死?

又莫非系统资源不足,系统杀死?

又莫非?

同样针对这两种情况,排查结果:

报警的此接口并不是特别复杂的接口,执行时间也并不长,以前也并未出现过问题

通过zabbix、埋点监控、系统负载查看,cpu、内存、fpm整体进程情况也比较正常

顺便也看了下 fpm的错误日志、慢日志,也没有什么收获(此处很可能会忽略掉了重要信息)

蛛丝马迹

于是既然认为是fpm出了问题,就调研下fpm的配置文件吧

摘自 https://www.zybuluo.com/phper/note/89081

单独拿出几个重要配置项:

开始学习

以上便是我们线上的主要配置,主要还是集中在了 request_terminate_timeout 这个参数上。它和php.ini的 max_execution_time 有什么区别

set_time_limit()函数和配置指令max_execution_time只影响脚本本身执行的时间。任何发生在诸如使用system()的系统调用,流操作,数据库操作等的脚本执行的最大时间不包括其中,而 request_terminate_timeout 是包含所有时间的

php.ini配置时间同样也为30,但是相比而言,request_terminate_timeout时间会更短。

回归正题

但前文我们明明说了,这个接口并不是很复杂啊。..应该不会超时啊,当时第三方服务也没有什么异常情况,fpm错误日志也并没有这个超时错误信息。各个依赖的系统负载都还处于比较低峰期状态

在疑问中结束了今天的工作,回来打算写一下分享今天的调试经历,在搜索文档的时候又发现了这么一句话:

复制别人文章

Nginx 502 Bad Gateway错误

在php.ini和php-fpm.conf中分别有这样两个配置项:max_execution_time和request_terminate_timeout。

这两项都是用来配置一个PHP脚本的最大执行时间的。当超过这个时间时,PHP-FPM不只会终止脚本的执行,

还会终止执行脚本的Worker进程。所以Nginx会发现与自己通信的连接断掉了,就会返回给客户端502错误。

以PHP-FPM的request_terminate_timeout=30秒时为例,报502 Bad Gateway错误的具体信息如下:

1)Nginx错误访问日志:

2013/09/19 01:09:00 [error] 27600#0: *78887 recv() failed (104: Connection reset by peer) while reading response header from upstream,

client: 192.168.1.101, server: test.com, request: "POST /index.php HTTP/1.1", upstream: "fastcgi://unix:/dev/shm/php-fcgi.sock:",

host: "test.com", referrer: "http://test.com/index.php"

2)PHP-FPM报错日志:

所以只需将这两项的值调大一些就可以让PHP脚本不会因为执行时间长而被终止了。

request_terminate_timeout可以覆盖max_execution_time,所以如果不想改全局的php.ini,那只改PHP-FPM的配置就可以了。

此外要注意的是Nginx的upstream模块中的max_fail和fail_timeout两项。有时Nginx与上游服务器(如Tomcat、FastCGI)的通信只是偶然断掉了,但max_fail如果设置的比较小的话,那么在接下来的fail_timeout时间内,Nginx都会认为上游服务器挂掉了,都会返回502错误。所以可以将max_fail调大一些,将fail_timeout调小一些。

摘自: http://blog.51cto.com/nanchunle/1657410

自圆其说

对于nginx的upstream模块并不是很了解,回忆当时报错场景,确实发现日志里面前后报了几个不同接口同样的错误,也可能是其他接口影响了此接口,只是它正好被报警系统抓取到。

反思

思考问题可能过于片面,没有解决问题的一套体系、思路,容易绕弯路、甚至南辕北辙。

结论

这是一篇没有结论的文章.

后续会尝试复现此场景,希望大家持续关注。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190215G1BBBH00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券