基于本文回答

播面 播面

刷题像听歌,多听自然懂
0
评论

如何配置 Nginx 以支持后端服务器的被动健康检查和主动健康检查?

在 Nginx 中配置健康检查可以确保请求只会被路由到健康的后端服务器,从而提高整个系统的高可用性。

Nginx 的健康检查分为被动健康检查(Passive Health Checks)主动健康检查(Active Health Checks)

需要特别注意的是:开源免费版的 Nginx 原生只支持被动健康检查。如果要使用主动健康检查,可以通过使用商业版(Nginx Plus)、重新编译加入第三方模块,或者使用基于 Nginx 的分支(如 Tengine)。

下面是具体的配置方法:


一、 被动健康检查(Passive Health Checks)

适用版本:所有版本(开源版 Nginx 和 Nginx Plus 均支持)。
工作原理:Nginx 依靠真实的客户端流量来判断后端状态。如果 Nginx 转发请求给某台后端服务器失败达到一定次数,Nginx 会将该服务器标记为“不可用”一段时间,在此期间不再将请求转发给它。

配置示例:

修改 nginx.conf 中的 upstream 模块:

plaintext
http {
    upstream backend_servers {
        # max_fails: 允许请求失败的次数,默认为 1。
        # fail_timeout: 在此时间内发生 max_fails 次失败,则认为服务器宕机;且宕机后的恢复等待时间也是这个值。默认为 10s。
        
        server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
        server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
        
        # 备用服务器,只有当上面两台都 down 掉时,才会使用这一台
        server 192.168.1.12:8080 backup;
    }

    server {
        listen 80;
        server_name example.com;

        location / {
            proxy_pass http://backend_servers;
            
            # 定义什么样的情况算作“失败”(配合 max_fails 使用)
            proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
        }
    }
}

参数解析

  • 192.168.1.1030秒内 发生 3次 失败(失败的定义由 proxy_next_upstream 决定,如超时或502错误)时,Nginx 会将其标记为 down。
  • 在接下来的 30秒 内,Nginx 不会发送任何请求给这台服务器。
  • 30秒过后,Nginx 会尝试将一个客户端请求转发给它。如果成功,则认为它恢复健康;如果再次失败,则继续标记为 down 30秒。

二、 主动健康检查(Active Health Checks)

工作原理:Nginx 在后台定时向后端服务器发送探测请求(如 HTTP GET /health),根据服务器的响应(如状态码是否为 200)来判断其是否健康,而不依赖于真实的客户端流量。

因为开源版和商业版的实现方式不同,这里分两种情况:

情况 A:使用开源版 Nginx + 第三方模块(最常用)

开源版 Nginx 需要重新编译并添加淘宝开源的 nginx_upstream_check_module 模块,或者直接使用自带该模块的 Tengine

配置示例(基于 nginx_upstream_check_module):

plaintext
http {
    upstream backend_servers {
        server 192.168.1.10:8080;
        server 192.168.1.11:8080;

        # 主动健康检查配置
        # interval: 检查间隔,单位为毫秒(这里是3秒)
        # rise: 连续成功多少次认为服务器是健康的(这里是2次)
        # fall: 连续失败多少次认为服务器宕机(这里是3次)
        # timeout: 健康检查的超时时间,单位为毫秒(这里是2秒)
        # type: 检查类型(支持 tcp, http, ssl_hello, mysql 等)
        check interval=3000 rise=2 fall=3 timeout=2000 type=http;
        
        # 发送的 HTTP 探针请求内容
        check_http_send "HEAD /health_check HTTP/1.0\r\n\r\n";
        
        # 期望返回的 HTTP 状态码
        check_http_expect_alive http_2xx http_3xx;
    }

    server {
        listen 80;
        
        location / {
            proxy_pass http://backend_servers;
        }

        # 可选:提供一个健康检查状态的监控页面
        location /status {
            check_status;
            access_log off;
            # 建议加上访问控制
            # allow 127.0.0.1;
            # allow 192.168.1.0/24;
            # deny all;
        }
    }
}

情况 B:使用 Nginx Plus(官方商业版)

如果你使用的是商业版的 Nginx Plus,可以直接使用原生的 health_check 指令。

配置示例(Nginx Plus):

plaintext
http {
    upstream backend_servers {
        # 必须配置 zone,用于在所有 worker 进程间共享状态
        zone backend 64k;
        server 192.168.1.10:8080;
        server 192.168.1.11:8080;
    }

    # 定义健康检查的匹配规则
    match conditions {
        status 200;
        header Content-Type = text/html;
        body ~ "OK";
    }

    server {
        listen 80;

        location / {
            proxy_pass http://backend_servers;
            
            # 开启主动健康检查
            # interval: 检查间隔
            # passes: 连续成功多少次算健康
            # fails: 连续失败多少次算不健康
            # uri: 检查的接口路径
            # match: 匹配上面定义的 conditions
            health_check interval=5s passes=2 fails=3 uri=/health match=conditions;
        }
    }
}

总结与建议

  1. 基本场景:如果没有特殊需求,开源版的 被动健康检查 (max_fails) 已经能满足 80% 的需求。
  2. 高要求场景:如果后端服务器启动较慢,或者希望在请求到达前就剔除故障节点,必须使用主动健康检查
  3. 技术选型
    • 预算充足:直接购买 Nginx Plus。
    • 零预算且不想折腾:更换为 Tengine (阿里开源),内置了主动健康检查。
    • 零预算且技术能力强:在现有的 Nginx 源码上打补丁并编译 nginx_upstream_check_module
00:00
00:00