昨天商家客服报了一个问题,有商家返回订单无法下载。我测试了一下,当下载时间超过10秒时,连接被强行断开,并在页面抛出504。
查看nginx日志,发现对应的请求返回的错误码为”499”。

“499”是nginx自定义错误码,意思是“客户端主动关闭连接”,就是PHP脚本执行的时间太长了,调用方关闭了连接。

解决过程:

1. 先确认是否是代码问题

报499的一个可能原因就是,有人调小了curl请求的超时时间,curl超时之后调用方主动关闭了连接。

  • 我先是查看了所有与该业务相关的代码的”svn log”,确定最近一段时间没有对相关代码修改。
  • 然后我去预上线环境测试了一下,尝试多次后,都没有出现该问题,那就应该不是代码的问题。

结论:代码问题被排除,有很大可能是线上环境问题。

2. 确认是否是环境问题

还是从日志着手

  • 取出了所有报“499”的php机器IP,不幸的是,所有机器都出现了这种问题,而且都是10s就断开连接。
  • 取出了所有报错的nginx机器的IP,好吧,也没发现规律。

其实,到这里,我完全可以把这个问题交给sys那边了,因为已经确定不是我们这边代码的问题了。

  • 检查nginx配置文件相关参数,fastcgi_read_timeout参数设置的是60s,不会导致这个问题。
  • 检查php机器上的php.ini,虽然max_execution_time参数的值是10s,但是我在php的脚本里面使用set_time_limit函数临时将脚本的最长执行时间改为了600s,所以也不是这个问题。
  • 检查php-fpm.conf,request_terminate_timeout参数没有设置,那就是不会限制cgi接口读取数据的时间,php-fpm的问题也被排除了。

到这里我已经开始怀疑人生了。

3. 纠结了3个小时之后,还是丢给sys解决

负责我们组线上机器配置的sys也纠结了两个小时。
最后,终于找到了问题,最近为迎接大促,新上了流控系统,使用的是openresty。
前几天新系统上线的时候就出现了这类问题,但是openresty的配置被多人修改的很乱,有几个地方漏改了。他排查了所有的nginx机器,将

1
2
proxy_read_timeout 10s;
proxy_send_timeout 10s;

改为

1
2
proxy_read_timeout 60s;
proxy_send_timeout 60s;

然后重启openresty,问题解决了。

后记

╮(╯▽╰)╭,纠结死我了,以后这种问题确认不是我们这边代码的问题,直接丢给sys,浪费我这么长时间。