千家信息网

线上nginx的no live upstreams while connecting to upstream 示例分析

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,线上nginx的no live upstreams while connecting to upstream 示例分析,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这
千家信息网最后更新 2026年11月01日线上nginx的no live upstreams while connecting to upstream 示例分析

线上nginx的no live upstreams while connecting to upstream 示例分析,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

先描述一下环境,前段的负载均衡转发给nginx,nginx再转发给后端的应用服务器。

nginx配置文件如下:

upstream ads {

server ap1:8888 max_fails=1 fail_timeout=60s;

server ap2:8888 max_fails=1 fail_timeout=60s;

}

出现的现象是:

日志里面每隔一两分钟就会记录一条类似 *379803415 no live upstreams while connecting to upstream 的日志,

此外,还有大量的"upstream prematurely closed connection while reading response header from upstream"的日志。

我们先看"no live upstreams"的问题。

看字面意思是nginx发现没有存活的后端了,但是很奇怪的事情是,这段时间一直访问都正常,并且用wireshark看到的也是有进来的,也有返回的。

现在只能从nginx源码的角度来看了。

因为是upstream有关的报错,所以在ngx_http_upstream.c中查找"no live upstreams"的关键字,可以找到如下代码(其实,你会发现,如果在nginx全局代码中找的话,也只有这个文件里面有这个关键字):

在这里可以看出,当rc等于NGX_BUSY的时候,就会记录"no live upstreams"的错误。

往上看1328行,可以发现rc的值又是ngx_event_connect_peer这个函数返回的。

ngx_event_connect_peer是在event/ngx_event_connect.c中实现的。这个函数中,只有这个地方会返回NGX_BUSY,其他地方都是NGX_OK或者NGX_ERROR或者NGX_AGAIN之类的。

rc = pc->get(pc, pc->data);

if (rc != NGX_OK) {

return rc;

}

这里的pc是指向ngx_peer_connection_t结构体的指针, get是个ngx_event_get_peer_pt的函数指针,具体指向哪里,一时无从得知。接着翻看ngx_http_upstream.c

在ngx_http_upstream_init_main_conf中看到了,如下代码:

uscfp = umcf->upstreams.elts;

for (i = 0; i < umcf->upstreams.nelts; i++) {

init = uscfp[i]->peer.init_upstream ? uscfp[i]->peer.init_upstream:

ngx_http_upstream_init_round_robin;

if (init(cf, uscfp[i]) != NGX_OK) {

return NGX_CONF_ERROR;

}

}

这里可以看到,默认的配置为轮询(事实上负载均衡的各个模块组成了一个链表,每次从链表到头开始往后处理,从上面到配置文件可以看出,nginx不会在轮询前调用其他的模块),并且用ngx_http_upstream_init_round_robin初始化每个upstream。

再看ngx_http_upstream_init_round_robin函数,里面有如下行:

r->upstream->peer.get = ngx_http_upstream_get_round_robin_peer;

这里把get指针指向了ngx_http_upstream_get_round_robin_peer

在ngx_http_upstream_get_round_robin_peer中,可以看到:

if (peers->single) {

peer = &peers->peer[0];

if (peer->down) {

goto failed;

}

} else {

/* there are several peers */

peer = ngx_http_upstream_get_peer(rrp);

if (peer == NULL) {

goto failed;

}

再看看failed的部分:

failed:

if (peers->next) {

/* ngx_unlock_mutex(peers->mutex); */

ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0, "backup servers");

rrp->peers = peers->next;

n = (rrp->peers->number + (8 * sizeof(uintptr_t) - 1))

/ (8 * sizeof(uintptr_t));

for (i = 0; i < n; i++) {

rrp->tried[i] = 0;

}

rc = ngx_http_upstream_get_round_robin_peer(pc, rrp);

if (rc != NGX_BUSY) {

return rc;

}

/* ngx_lock_mutex(peers->mutex); */

}

/* all peers failed, mark them as live for quick recovery */

for (i = 0; i < peers->number; i++) {

peers->peer[i].fails = 0;

}

/* ngx_unlock_mutex(peers->mutex); */

pc->name = peers->name;

return NGX_BUSY;

这里就真相大白了,如果连接失败了,就去尝试连下一个,如果所有的都失败了,就会进行quick recovery 把每个peer的失败次数都重置为0,然后再返回一个NGX_BUSY,然后nginx就会打印一条no live upstreams ,最后又回到原始状态,接着进行转发了。

这就解释了no live upstreams之后还能正常访问。

重新看配置文件,如果其中一台有一次失败,nginx就会认为它已经死掉,然后就会把以后的流量全都打到另一台上面,当另外一台也有一次失败的时候,就认为两个都死掉了,然后quick recovery,然后打印一条日志。

这样带来的另一个问题是,如果几台同时认定一台后端已经死掉的时候,会造成流量的不均衡,看zabbix监控的截图也能看出来:

初步的解决方法:

把max_fails从1改成5,效果很明显,"no live upstreams"出现的概率变少了很多,但却没有完全消失。

另外,日志里面还会有大量的"upstream prematurely closed connection while reading response header from upstream"。

这次从源码上看,在执行ngx_http_upstream_process_header这个函数的时候,会报这个错,但具体是网络原因还是其他原因不是很明显,下面就tcpdump抓一下包。

其中54是nginx前端的负载均衡的地址,171是nginx地址,32是ap1的地址,另外ap2的地址是201

如截图所示:

请求由负载均衡发到nginx上,nginx先是回应ack给负载均衡,然后跟ap1进行三次握手,随后发送了一个长度为614的数据包给ap1.然而却收到了一个ack和fin+ack,从Ack=615可以看出,这两个包都是针对长度为614的数据包的回应,后端app直接就把连接给关闭掉了!

再然后,nginx回应给后端的app一个ack和fin+ack,从Ack=2可以看出这是对fin+ack的回应。

再然后,nginx就向ap2发出了一个syn包,并且也收到了第一台返回的ack。

第二张图:

如图,可以看出,nginx跟ap2三次握手后,也发送了一个请求的数据包,同样被直接关闭连接了。

随后,nginx就把502返回给了负载均衡。

这里的抓包又一次从侧面支持了上面代码的分析。

然后把问题反馈给做后端应用的同事了。

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注行业资讯频道,感谢您对的支持。

均衡 函数 日志 代码 地址 文件 时候 配置 指向 指针 数据 问题 分析 明显 两个 关键 关键字 原因 只有 地方 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技未来 科技类互联网 深圳科技互联网 礼当家互联网科技 互联网女皇 腾讯科技 沃里互联网科技 互联网科技的未来发展 成都狮子座互联网科技 联恩商钥互联网科技有限公司 无锡溥仪互联网科技有限公司 华中科技有哪些互联网大佬 港股科技和互联网 互联网科技革命什么开始 河南住房之家互联网科技 长沙茂晟互联网科技有限公司 四川慕妮娅互联网科技有限公司 华中科技大学互联网的牛人 广东工业互联网大赛深圳学泰科技 广州富喜互联网络科技 恒生科技互联网指数十大成分股 高科技互联网 互联网公司 科技公司 富国互联网科技创新基金 开启互联网科技时代小说 中国科技互联网公司收入 徐州市互联网科技有限公司 互联网科技公司营业执照怎么办理 工业互联网科技创业 2021世界互联网领先科技成果发布 北京品多多互联网科技有限公司
0