“no live upstreams”错误本质是Nginx因TCP连接积压导致健康检查失败而熔断所有上游节点,需结合accept()失败日志、ss -lnt的Recv-Q及ListenOverflows计数确认队列溢出,并同步调优somaxconn、backlog与worker_connections。

直接看 /var/log/nginx/error.log 里有没有反复出现 “accept() failed” 或 “no live upstreams” 类报错,再结合系统指标确认是否 TCP 连接积压。这类问题本质不是配置写错了,而是连接请求在内核 accept 队列里排队超时被丢弃,日志不会明说“队列满了”,但会暴露上游不可用、连接拒绝或 accept 失败等表象。
盯住 error_log 中的 accept 相关错误
真正反映 TCP 积压的典型日志不是 502 或超时,而是:
- “accept() failed (24: Too many open files)”:说明进程级文件描述符耗尽,无法 accept 新连接;
-
“accept() failed (11: Resource temporarily unavailable)”:通常对应内核 accept 队列满(
listen backlog溢出),Nginx 调用accept()立即返回 EAGAIN; - “no live upstreams while connecting to upstream”:表面是上游全挂,实则是 upstream 健康检查因连接积压失败,节点被摘除,形成恶性循环;
- 连续出现 “connect() failed (111: Connection refused)” 且
$upstream_addr显示为空或地址反复变化:说明 upstream 地址解析后连接失败,可能因上游服务因积压已不响应 SYN。
用 ss 和 netstat 验证 accept 队列状态
仅看日志不够,必须立刻查系统层面的连接队列:
- 执行
ss -lnt,关注Recv-Q列:若某端口的Recv-Q持续 > 0(尤其接近或等于你配置的listen ... backlog=xxx值),说明 accept 队列已满; - 运行
netstat -s | grep -A 5 "Listen"或cat /proc/net/snmp | grep Tcp,查找ListenOverflows和ListenDrops计数——这两个值一旦非零,就证实有连接在内核队列里被静默丢弃; - 检查
/proc/sys/net/core/somaxconn是否小于 Nginx 的backlog设置:如果 Nginx 配了listen 80 backlog=8192,但somaxconn是默认的 128,那实际生效的仍是 128。
关联排查上游与健康检查行为
TCP 积压常引发连锁反应,error_log 里的异常往往是结果而非原因:
- 检查 upstream 块是否启用了
max_fails和fail_timeout:当上游因积压响应变慢或超时,Nginx 会连续标记失败,最终整组 upstream 被熔断,后续请求全部报 “no live upstreams”; - 确认
proxy_next_upstream是否包含timeout或error:若开启,一次积压导致的超时会被重试,加剧下游压力; - 对比
error.log时间戳和access.log中 502/504 请求的时间分布:若大量 504 出现在同一秒内,大概率是 accept 队列溢出后,Nginx 批量 fallback 到 backup 或直接报错。
调整关键参数并验证效果
定位后需同步调优 Nginx 和内核两层:
- Nginx 配置中,在
listen指令显式加大backlog,例如:listen 80 backlog=8192;; - 提升内核限制:
echo 32768 > /proc/sys/net/core/somaxconn(临时),并写入/etc/sysctl.conf持久化; - 增大
tcp_max_syn_backlog(应对 SYN 队列积压):echo 65536 > /proc/sys/net/ipv4/tcp_max_syn_backlog; - 检查
worker_connections是否足够:它决定单个 worker 能处理多少并发连接,应 ≥backlog × worker_processes; - 上线后观察
ListenOverflows是否归零,并用ab或wrk模拟突发流量验证稳定性。


















