Nginx反向代理与负载均衡配置实战:upstream健康检查与会话保持策略

Nginx作为反向代理服务器,通过upstream模块实现后端节点间的流量分发。负载均衡配置不只是轮询分发请求,还涉及健康检查、会话保持、故障转移等生产级需求。在高并发场景下,upstream的调度算法和连接参数直接影响后端服务的稳定性和响应速度。

Nginx upstream负载均衡算法配置

Nginx原生支持四种负载均衡算法:轮询(默认)、加权轮询、ip_hash(按客户端IP哈希)、least_conn(最少连接数)。每种算法适用于不同的业务场景。

# nginx.conf - upstream基础配置
upstream backend_api {
    # 加权轮询:性能强的节点分配更多请求
    server 10.0.1.10:8080 weight=3 max_fails=3 fail_timeout=30s;
    server 10.0.1.11:8080 weight=2 max_fails=3 fail_timeout=30s;
    server 10.0.1.12:8080 weight=1 max_fails=3 fail_timeout=30s;
    
    # 备用节点:主节点全部不可用时启用
    server 10.0.1.20:8080 backup;
    
    # 连接保持:减少TCP握手开销
    keepalive 32;
    keepalive_timeout 60s;
    keepalive_requests 1000;
}

# ip_hash:同一客户端IP固定访问同一后端节点
upstream backend_session {
    ip_hash;
    server 10.0.1.10:8080;
    server 10.0.1.11:8080;
}

# least_conn:优先分发到当前连接数最少的节点
upstream backend_compute {
    least_conn;
    server 10.0.1.10:8080 weight=3;
    server 10.0.1.11:8080 weight=2;
}

server {
    listen 80;
    server_name api.example.com;
    
    location /api/ {
        proxy_pass http://backend_api;
        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_connect_timeout 5s;
        proxy_read_timeout 30s;
        proxy_send_timeout 10s;
    }
}

被动健康检查与故障自动剔除

Nginx内置的被动健康检查通过max_fails和fail_timeout参数实现。当某节点在fail_timeout时间内失败次数达到max_fails,Nginx自动将其标记为不可用,在fail_timeout时间过后再次尝试。

upstream backend {
    server 10.0.1.10:8080 max_fails=3 fail_timeout=30s;
    server 10.0.1.11:8080 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_tries 3;
        proxy_next_upstream_timeout 10s;
    }
}

# 验证健康检查效果
# curl http://10.0.1.10:8080/health -> 502
# Nginx自动将请求转发到10.0.1.11
# tail -f /var/log/nginx/error.log
# 可看到 "upstream timed out" 和自动切换日志

主动健康检查:nginx_upstream_check_module

upstream backend {
    server 10.0.1.10:8080;
    server 10.0.1.11:8080;
    server 10.0.1.12:8080;
    
    # 主动健康检查
    check interval=3000 rise=2 fall=3 timeout=2000 type=http;
    # interval=3000: 每3秒检查一次
    # rise=2: 连续2次成功标记为健康
    # fall=3: 连续3次失败标记为不健康
    
    check_http_send "GET /health HTTP/1.0\r\n\r\n";
    check_http_expect_alive http_2xx http_3xx;
}

server {
    listen 80;
    # 健康检查状态页
    location /upstream_status {
        check_status;
        access_log off;
        allow 10.0.0.0/8;
        deny all;
    }
    location / {
        proxy_pass http://backend;
    }
}

会话保持方案:sticky cookie与一致性哈希

# 基于Lua的一致性哈希(开源方案)
lua_package_path "/usr/local/lib/lua/?.lua;;";

upstream backend {
    server 10.0.1.10:8080;
    server 10.0.1.11:8080;
    server 10.0.1.12:8080;
    keepalive 32;
}

server {
    listen 80;
    
    location /api/ {
        access_by_lua_block {
            local chash = require "resty.chash"
            local nodes = {
                ["10.0.1.10:8080"] = 100,
                ["10.0.1.11:8080"] = 100,
                ["10.0.1.12:8080"] = 100,
            }
            local men = chash:new({nodes = nodes})
            local key = ngx.var.arg_user_id or ngx.var.remote_addr
            local node = men:find(key)
            ngx.var.upstream_addr = node
        }
        proxy_pass http://backend;
    }
}

故障排查:upstream连接超时与502诊断

# 1. 检查后端服务是否存活
curl -v http://10.0.1.10:8080/health
# 连接拒绝 -> 后端进程未启动或端口未监听
# 超时 -> 防火墙阻断或后端过载

# 2. 检查Nginx错误日志定位具体原因
tail -f /var/log/nginx/error.log | grep upstream
# "connect() failed (111: Connection refused)" -> 后端未启动
# "upstream timed out" -> 后端响应过慢
# "no live upstreams" -> 所有后端节点被剔除

# 3. 系统层面排查
ss -s | grep TIME-WAIT
sysctl -w net.ipv4.tcp_tw_reuse=1
sysctl -w net.ipv4.tcp_max_tw_buckets=5000

# 4. 检查文件描述符限制
ulimit -n
# worker_connections 10240 -> 需要ulimit -n至少10240
echo "* soft nofile 65535" >> /etc/security/limits.conf
echo "* hard nofile 65535" >> /etc/security/limits.conf

# 5. Nginx访问日志添加upstream响应时间
log_format upstream_log '$remote_addr - $request_time '
    '$upstream_response_time $upstream_addr $status';
access_log /var/log/nginx/access.log upstream_log;
# $upstream_response_time > 30s 说明后端处理过慢

Nginx负载均衡配置需要结合业务特点选择调度算法。无状态API服务用加权轮询,计算密集型任务用least_conn,有状态服务配置会话保持。生产环境务必配置主动健康检查和连接保持,避免单节点故障引发雪崩。监控upstream响应时间和错误率,结合自动扩缩容策略应对流量波动。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/nginx-fan-xiang-dai-li-yu-fu-zai-jun-heng-pei-zhi-shi-zhan/

(0)
小编小编
上一篇 7小时前
下一篇 7小时前

相关推荐