记一次网关线上事故
链路:
基础运维20台nginx集群 -> APISIX网关 04机房2台节点 -> 云平台04 -> 服务方
事故现象:
A业务请求量突增,大量返回499且响应时间都为30s左右,导致该域名下的其余业务返回502
基础运维层:
域名的超时时间是连接connect:10s, read:30s, send:180s
upstream xxx {
server ip1:port1 max_fails = 20 fail_timeout = 10s;
server ip2:port2 max_fails = 20 fail_timeout = 10s;
keepalive 60;
}
经过排查,发现运维层error.log中出现”no live upstreams”
理清了原因:运维层与APISIX网关层的读超时时间是30s,由于A业务请求量突增,后端服务方处理不过来一直无响应,导致运维层nginx读超时主动断开连接,并记录504,处于proxy_next_upstream涵盖内的参数,因此被max_fails计数。由于04机房的业务很少,A业务的请求量突增导致占据了总体APISIX04机房请求的大比例,运维层的max_fails很容易到达20次(连续),因此在20台节点中的某些节点会触发熔断。当2个APISIX04节点都被熔断时,upstream ai-unfied-gateway-v2域名下就没有可用的upstream了,因此报错“no live upstreams”,并在熔断时间fail_timeout=10s内对所有请求返回502。
检查发现APISIX与云平台之间的超时时间被误设为6000s(单位问题,本应是6s)
改进方案:
- 随着链路的延伸,超时时间应该是越来越小,所以APISIX与云平台之间的超时时间要小于运维层与APISIX之间的超时时间。这样APISIX就可以先断掉,而不是运维那边先断掉。
- 并且把运维层proxy_next_upstream中的错误码去掉,避免误触熔断。