Skip to content

Nginx upstream 健康检查与被动熔断配置

Nginx upstream 健康检查与被动熔断配置示意图

前面三章,我们完成了架构设计、原理学习和健康检查服务的开发。现在终于到了真正让 Nginx 动起来的时候。

本章将手把手配置 Nginx 的 upstream 健康检查被动熔断 机制,让 Nginx 能够自动识别并摘除故障节点。

一、Nginx 在这个架构中的角色

回顾一下整体架构:

Nginx 在这一层承担了三个关键职责:

职责说明
反向代理接收所有请求,转发给后端的 Master 集群
健康检查定期探测 Master 是否存活,自动摘除故障节点
负载均衡多个 Master 节点之间分发请求(可选)

💡 在我们的架构中,Nginx 和后端 Master 是同机部署的(Nginx 和 Master 运行在同一台物理机上)。这意味着:

  • Nginx 代理的是 127.0.0.1:8080,而不是其他机器的 IP
  • 健康检查针对的是本机的 Master 服务

二、环境准备:安装 Nginx

在开始配置之前,需要在三台机器(192.168.0.201192.168.0.202192.168.0.203)上分别完成 Nginx 的安装。

2.1 安装 Nginx

bash
# 更新软件包索引
sudo apt update

# 安装 Nginx
sudo apt install -y nginx

# 查看版本,确认安装成功
nginx -v
# 输出:nginx version: nginx/1.18.0 (Ubuntu)

2.2 验证 Nginx 是否正常运行

bash
# 检查 Nginx 服务状态
sudo systemctl status nginx

# 测试 Nginx 默认页面
curl http://localhost
# 应该能看到 Nginx 的欢迎页面

2.3 确保 Nginx 开机自启

bash
sudo systemctl enable nginx

2.4 确认安装路径和配置文件位置

bash
# 查看 Nginx 安装路径
whereis nginx
# nginx: /usr/sbin/nginx /etc/nginx /usr/share/nginx

# 查看主配置文件
ls -la /etc/nginx/
# 重点关注:nginx.conf、sites-available/、sites-enabled/

💡 本节目标:三台机器全部完成 Nginx 安装,为后续的 upstream 配置做好准备。

三、Nginx 健康检查的两种模式

Nginx 提供了两种健康检查机制:

模式原理优点缺点
被动检查根据请求的响应状态(超时、拒绝、5xx)判断节点是否健康无需额外配置,自动生效故障节点至少会被请求一次才摘除
主动检查Nginx 定期主动发送探测请求(如 /health故障提前发现,不会影响到业务请求需要 Nginx Plus 或第三方模块

⚠️ 重要说明:Nginx 开源版不支持主动健康检查(主动发送探测请求)。主动检查是 Nginx Plus 付费版的功能。

但我们可以通过 被动检查 + Keepalived 健康检查脚本 的组合来达到同样的效果。这也是大多数生产环境的选择。关于 Keepalived 的配置,我们会在第 5 篇中完整覆盖。

四、被动健康检查配置

被动检查依赖几个核心参数:

参数作用推荐值
max_fails允许失败的最大次数,超过后标记为 down2
fail_timeout失败计数的时间窗口,同时也是标记 down 后的恢复尝试间隔10s
proxy_connect_timeout连接后端超时时间3s
proxy_read_timeout读取后端响应超时时间30s

4.1 基础 upstream 配置

在三台机器上重写默认的 nginx 站点配置文件:

bash
sudo vim /etc/nginx/sites-available/default

但是,具体到每台服务器上的 /etc/nginx/sites-available/default 配置文件会有细微的区别,主要是 upstream 的配置上!

nginx
# /etc/nginx/sites-available/default
upstream master_backend {
    # 同机部署,代理到本机的 8080 端口
    server 127.0.0.1:8080 max_fails=2 fail_timeout=10s;

    # 其他 Master 节点
    server 192.168.0.202:8080 max_fails=2 fail_timeout=10s;  
    server 192.168.0.203:8080 max_fails=2 fail_timeout=10s backup;  

    # 保持长连接,提高性能
    keepalive 32;
}

server {
    listen 80;
    server_name _;

    # 客户端请求体大小限制
    client_max_body_size 10M;

    location / {
        proxy_pass http://master_backend;

        # 请求头透传
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # 超时配置(影响被动检查的判断)
        proxy_connect_timeout 3s;
        proxy_read_timeout 30s;
        proxy_send_timeout 30s;

        # 长连接配置
        proxy_http_version 1.1;
        proxy_set_header Connection "";

        # 失败重试配置
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
        proxy_next_upstream_tries 2;
        proxy_next_upstream_timeout 10s;
    }

    # 独立的健康检查接口(可选,用于外部探测)
    location /nginx-health {
        access_log off;
        return 200 "nginx ok\n";
        add_header Content-Type text/plain;
    }
}
nginx
# /etc/nginx/sites-available/default
upstream master_backend {
    # 同机部署,代理到本机的 8080 端口
    server 127.0.0.1:8080 max_fails=2 fail_timeout=10s;

    # 其他 Master 节点
    server 192.168.0.201:8080 max_fails=2 fail_timeout=10s;  
    server 192.168.0.203:8080 max_fails=2 fail_timeout=10s backup;  

    # 保持长连接,提高性能
    keepalive 32;
}

server {
    listen 80;
    server_name _;

    # 客户端请求体大小限制
    client_max_body_size 10M;

    location / {
        proxy_pass http://master_backend;

        # 请求头透传
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # 超时配置(影响被动检查的判断)
        proxy_connect_timeout 3s;
        proxy_read_timeout 30s;
        proxy_send_timeout 30s;

        # 长连接配置
        proxy_http_version 1.1;
        proxy_set_header Connection "";

        # 失败重试配置
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
        proxy_next_upstream_tries 2;
        proxy_next_upstream_timeout 10s;
    }

    # 独立的健康检查接口(可选,用于外部探测)
    location /nginx-health {
        access_log off;
        return 200 "nginx ok\n";
        add_header Content-Type text/plain;
    }
}
nginx
# /etc/nginx/sites-available/default
upstream master_backend {
    # 同机部署,代理到本机的 8080 端口
    server 127.0.0.1:8080 max_fails=2 fail_timeout=10s;

    # 其他 Master 节点
    server 192.168.0.201:8080 max_fails=2 fail_timeout=10s;  
    server 192.168.0.202:8080 max_fails=2 fail_timeout=10s backup;  

    # 保持长连接,提高性能
    keepalive 32;
}

server {
    listen 80;
    server_name _;

    # 客户端请求体大小限制
    client_max_body_size 10M;

    location / {
        proxy_pass http://master_backend;

        # 请求头透传
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # 超时配置(影响被动检查的判断)
        proxy_connect_timeout 3s;
        proxy_read_timeout 30s;
        proxy_send_timeout 30s;

        # 长连接配置
        proxy_http_version 1.1;
        proxy_set_header Connection "";

        # 失败重试配置
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
        proxy_next_upstream_tries 2;
        proxy_next_upstream_timeout 10s;
    }

    # 独立的健康检查接口(可选,用于外部探测)
    location /nginx-health {
        access_log off;
        return 200 "nginx ok\n";
        add_header Content-Type text/plain;
    }
}

4.2 应用配置

执行以下命令,测试配置是否正确:

bash
nginx -t
# 输出:
# nginx: configuration file /etc/nginx/nginx.conf test is successful

执行以下命令,平滑热加载(零停机更新配置):

bash
nginx -s reload

# 或使用 systemctl
sudo systemctl reload nginx

4.3 参数详解

被动检查工作原理:

proxy_next_upstream 配置解读:

nginx
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
条件说明是否触发重试
error连接后端时发生错误
timeout连接、读取或发送超时
invalid_header后端返回无效的响应头
http_500后端返回 500 Internal Server Error
http_502后端返回 502 Bad Gateway
http_503后端返回 503 Service Unavailable
http_404后端返回 404(默认不触发)

五、验证 Nginx 被动检查

在部署 Keepalived 之前,我们先单独验证 Nginx 的被动健康检查机制是否正常工作。

5.1 确保 Master 服务正常运行

bash
# 在三台机器上分别确认 gateway 服务正在运行
sudo systemctl status gateway

# 如果没有运行,启动它
sudo systemctl start gateway

5.2 模拟 Master 服务故障

node1(192.168.0.201) 上停止 Master 服务:

bash
sudo systemctl stop gateway

5.3 发送请求触发被动检查

bash
# 在 node1(192.168.0.201)上本地测试
# 因为 Nginx 代理的是 127.0.0.1:8080,直接访问本机 Nginx 即可

for i in {1..5}; do
    curl -X POST http://127.0.0.1/api/v1/task \
         -H "Content-Type: application/json" \
         -d '{"test": "failover"}' \
         -w "\nHTTP Status: %{http_code}\n"
    sleep 1
done

5.4 观察 Nginx 错误日志

bash
# 在 node1 上查看 Nginx 错误日志
sudo tail -f /var/log/nginx/error.log

# 预期看到类似日志:
# [error] upstream timed out (110: Connection timed out) while connecting to upstream
# [error] no live upstreams while connecting to upstream

5.5 恢复 Master 服务并验证

bash
# 恢复 Master 服务
sudo systemctl start gateway

# 再次发送请求,观察节点重新变为可用
curl -X POST http://127.0.0.1/api/v1/task \
     -H "Content-Type: application/json" \
     -d '{"test": "recovery"}'

# 预期:请求成功,返回 200

5.6 验证结论

测试步骤预期结果是否通过
停止 Master 服务服务不可用通过
发送请求(第1-2次)Nginx 记录超时/错误通过
发送请求(第3次起)Nginx 直接返回错误,不再尝试转发通过
恢复 Master 服务等待 fail_timeout 后重新可用通过

💡 说明:本章验证用的是 127.0.0.1(本机 Nginx),不依赖 Keepalived。VIP 的验证将在第 5 篇部署完 Keepalived 后进行。

六、常见问题与解决方案

Q1:Nginx 开源版真的没有主动健康检查吗?

确实没有。 Nginx 开源版只支持被动健康检查。如果需要主动检查,可以考虑:

  • 购买 Nginx Plus
  • 使用 OpenResty(基于 Nginx 的增强版)
  • 使用第三方模块 nginx-upstream-check-module(需要重新编译 Nginx)
  • 使用 HAProxy 替代(原生支持主动检查)

Q2:max_failsfail_timeout 应该如何设置?

这取决于你的业务容忍度:

场景max_failsfail_timeout说明
高可用要求严格15s快速摘除,但可能误判
一般生产环境210s推荐配置,平衡速度和稳定性
网络不稳定330s避免频繁切换

Q3:如何让 Nginx 在重试时避开故障节点?

proxy_next_upstream 配合 max_fails 会自动实现。当一个节点失败次数达到 max_fails,Nginx 会在 fail_timeout 内不再将请求转发给它。

Q4:Nginx 和 Keepalived 的健康检查有什么区别?

组件检查对象发现问题后的动作
Nginx后端 Master 服务临时摘除节点,但 VIP 还在本机
KeepalivedNginx + Master 服务VIP 漂移到其他节点

两者配合形成完整的故障防护链。Keepalived 的配置将在第 5 篇中完整覆盖。

Q5:三台机器都要配置 Nginx 吗?

是的。 因为 VIP 可能漂移到任意一台机器,所以三台机器都需要安装 Nginx 并保持一致配置。这样无论 VIP 漂移到哪台机器,Nginx 都能正常工作。

Q6:如何确保三台机器的 Nginx 配置一致?

推荐使用配置管理工具(如 Ansible)同步配置,或者手动在三台机器上执行相同的配置步骤。我们在本系列的后续章节中会提供一键部署脚本。

七、小结

本章完成了 Nginx 的 upstream 健康检查和熔断配置,核心要点:

  1. 环境准备:三台机器安装 Nginx,确认服务正常运行
  2. 被动检查:通过 max_fails + fail_timeout 实现自动摘除故障节点
  3. 超时配置proxy_connect_timeoutproxy_read_timeout 影响故障判定
  4. 重试策略proxy_next_upstream 定义哪些错误需要重试
  5. 独立验证:无需 Keepalived,单独验证 Nginx 被动检查机制

下一章,我们将正式部署 Keepalived,配置 VIP 漂移,让高可用入口真正运转起来。


💡 本文是《分布式高可用入口架构实战系列》第 4 篇

最后更新2026/06/21 16:32
如果你觉得这篇文章有帮助,或者想聊聊技术、工作,欢迎通过下面方式联系我:
contact fishfinal