Nginx 中实现熔断降级

336 阅读2分钟

1. 熔断机制(Circuit Breaking)

熔断的核心是当后端服务连续失败时,暂时停止向其转发请求。Nginx通过被动健康检查实现这一点。

配置示例:

http {
    upstream backend {
        server 192.168.1.2:80 max_fails=3 fail_timeout=30s; # 30秒内失败3次触发熔断
        server 192.168.1.3:80 max_fails=3 fail_timeout=30s;
    }

    server {
        listen 80;
        location / {
            proxy_pass http://backend;
            proxy_next_upstream error timeout http_500 http_502 http_503 http_504; # 触发熔断的条件
            proxy_next_upstream_timeout 5s; # 单个请求超时时间
            proxy_next_upstream_tries 2;    # 最多尝试2个后端服务器
        }
    }
}
  • max_failsfail_timeout:在fail_timeout时间内失败max_fails次,则标记为不可用。
  • proxy_next_upstream:指定触发熔断的HTTP状态码(如5xx错误)或连接错误(如超时)。

2. 降级机制(Fallback)

当后端服务不可用时,返回预设的降级内容(如静态页、缓存数据或默认响应)。

配置示例:

server {
    listen 80;
    location / {
        proxy_pass http://backend;
        proxy_intercept_errors on;          # 允许拦截后端错误
        error_page 502 503 504 =200 /fallback; # 将502/503/504错误转为200并返回降级内容
    }

    location = /fallback {
        internal; # 仅内部跳转
        return 200 '{"status": "降级模式", "data": "默认响应"}'; # 返回JSON
        # 或返回静态文件:
        # root /var/www/fallback;
        # try_files /fallback.html =404;
    }
}

3. 限流(Rate Limiting)

通过限制请求速率防止系统过载,结合降级返回友好提示。

配置示例:

http {
    limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s; # 每秒10个请求

    server {
        listen 80;
        location / {
            limit_req zone=req_limit burst=20 nodelay; # 突发流量缓冲20个请求
            limit_req_status 429; # 超出限制时返回429状态码

            proxy_pass http://backend;
            error_page 429 = @too_many_requests;
        }

        location @too_many_requests {
            return 429 '{"error": "请求过多,请稍后重试"}';
        }
    }
}

4. 主动健康检查(Nginx Plus 版本)

Nginx Plus支持主动健康检查,定期探测后端服务状态。

配置示例:

upstream backend {
    zone backend 64k;
    server 192.168.1.2:80;
    server 192.168.1.3:80;

    # 主动健康检查配置
    health_check interval=5s uri=/health_check fails=3 passes=2;
}

# 健康检查端点需返回2xx状态码表示健康

5. 备份服务器(Backup Server)

当所有主服务器不可用时,启用备份服务器。

upstream backend {
    server 192.168.1.2:80;
    server 192.168.1.3:80;
    server 192.168.1.4:80 backup; # 标记为备份服务器
}

完整示例:熔断 + 降级 + 限流

http {
    limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;

    upstream backend {
        server 192.168.1.2:80 max_fails=3 fail_timeout=30s;
        server 192.168.1.3:80 max_fails=3 fail_timeout=30s;
        server 192.168.1.4:80 backup;
    }

    server {
        listen 80;
        proxy_intercept_errors on;

        location / {
            limit_req zone=req_limit burst=20 nodelay;
            limit_req_status 429;

            proxy_pass http://backend;
            proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
            proxy_next_upstream_timeout 5s;

            error_page 502 503 504 429 =200 @fallback;
        }

        location @fallback {
            return 200 '{"status": "降级模式", "data": "服务暂不可用"}';
            # 或返回静态文件:
            # root /var/www/fallback;
            # try_files /fallback.html =404;
        }
    }
}

验证方法

  1. 触发熔断:关闭后端服务,观察Nginx日志(tail -f /var/log/nginx/error.log)。
  2. 测试降级:访问接口,确认返回预设的降级内容。
  3. 限流测试:使用压测工具(如abwrk)发送大量请求,确认超出速率后返回429。

注意事项

  • 参数调优:根据实际场景调整max_failsfail_timeout和限流速率。
  • 监控报警:结合Prometheus + Grafana监控Nginx状态,及时发现问题。
  • 版本差异:主动健康检查仅Nginx Plus支持,开源版需用第三方模块(如nginx_upstream_check_module)。