Nginx 返回 502异常排查定位 (no live upstreams while connecting to upstream)

问题出现:

线上异常告警,如图:

Nginx 返回 502异常排查定位 (no live upstreams while connecting to upstream)

Nginx 返回 502异常排查定位 (no live upstreams while connecting to upstream)

总的来说,就是各种对外接口频繁出现偶发性的商户请求不通,同时集中在同一项目部署的应用,Nginx 502 告警,并报错日志 no live upstreams while connecting to upstream。

排查过程:

顾名思义:这个报错是没有上游可用,但是是什么原因导致呢?对于Nginx而言,出现这个报错存在很多的可能性,大致可以有:①Nginx资源不足 ②上游服务器异常 ③上游应用业务异常 等等。 

然后排查过程中,需要思考的因素蛮多的,首先运维很快就排除了①,有同事提议可能性②:可不可能是并发导致上游应用资源不足? 导致tomcat连接数不足?详情可以参考此文章:https://www.cnblogs.com/zjfjava/p/10909087.html

我看下了当时的并发数,可以很快推定,不是这个原因导致的。所以原因②几乎不成立。所以重点回到③。然后大伙查日志发现Nginx还有个很重要的信息。如图:

Nginx 返回 502异常排查定位 (no live upstreams while connecting to upstream)

 upstream server temporarily disabled while connecting to upstream。这个报错就很清楚明了,Nginx常规报错。初步判断是上游业务异常。

接下来顺藤摸瓜,开始排查对外接口,然后有一个接口,这里别名为 A。A接口感觉是我们不常用,为啥频繁出现请求,然后有看下参数,发现都是空传。初步判断是被攻击了。然后对A接口进行剖析(当然A接口已经被强制下线),发现报错mybatis,同时返回状态码为 500 。如图所示:Nginx 返回 502异常排查定位 (no live upstreams while connecting to upstream)

原因是A这个接口请求返回500,Nginx标记A所在上游不可用,然后轮询所有的上游都不可用,有其他的请求进来,Nginx直接返回502,内部报错无可用upstream。详情大家可以看下这篇博客。https://www.jianshu.com/p/6cf9bab3de50

再后来,运维通过修改  max_fails = 0。也验证我们排查问题的结论。

总结: 

①发生问题的原因是我们那个对外接口处理逻辑不正确,即商户请求进来并不是常规的验签验参(如果验签验参不通过,系统是会返回常规错误码 200),而是直接请求了数据库。上述问题相当于查全表操作了。才导致Mybatis报错,返回错误码 500,引发一系列的问题,同时写代码的思考。程序编程的时候,我们不单单要考虑如何实现业务,也要多一份思考去防止被攻击以及性能等的可能性。具体原因:https://www.jianshu.com/p/6cf9bab3de50

②排查问题是时候,都是和运维小伙伴一起排查,相互指引完成的。所以排查问题的时候,不能局限自身,多看各方意见,才能快速定位并解决问题。