问题背景:UI页面点击会偶尔返回error,检查调用日志,发现nginx报502报错,因此本文即排查502报错原因。
如下红框可知,访问本机个备机的服务502了,用时3秒左右(可见并不是超时)
先给出原因:是因为tomcat8默认的acceptCount是100,请求量大的时候,会将一些来不及处理的请求塞到acceptCount,当acceptCount塞满的时候,请求会被丢弃,即我们上面说的nginx报的502错误
解决方案:将acceptCount调大,目前线上调整到了10000,经16小时的观察,没有再报502错误,问题得以解决
排查过程:
怀疑一:首先发现DB的压力突增,见图,但是DBA帮排查后,这个时间点并没有慢查询,因此怀疑是否是服务器的问题
怀疑二:是不是有一台服务有问题
但是经排查nginx日志,两台服务都有502出现。因此这个情况排除
怀疑三:tomcat的本身的问题。
由于nginx现实502的时候,时间有的只有3秒或者更小,因此也不是访问tomcat超时的,所以最大的可能就是tomcat丢弃了请求,经确认确实是丢弃了。
怎么证明这个推断呢?
首先:看请求是否进入tomcat了,好在我们配置了tomcat的访问日志记录:配置如下:
日志:检查502请求的时间,在tomcat里面没有记录日志,可见并没有进入tomcat,从而论证了上面的观点:502是因为请求被丢弃了。
那么为什么会丢弃呢?
看了一些tomcat的默认配置,几个重要的配置:参考:Apache Tomcat 8 Configuration Reference (8.5.78) - The HTTP Connector
可见很重要的一个:acceptCount是100,第一感官,太小了,超过这个队列就被丢弃了。
acceptCount解释:当maxConnections超过10000万(tomcat默认值是10000)的时候,会将多余的连接放到acceptCount中,即默认的tomcat可以支持的最大连接数是10000 + 100 = 10100;
当超过10100的时候,请求就会被丢弃,即nginx的502日志,解决方法:将acceptCount调整成10000。502问题得以解决。
注:
maxConnections与acceptCount的关系
参考文档:
Apache Tomcat 8 Configuration Reference (8.5.78) - The HTTP Connector