Nginx 负载均衡配置详解:从基础到高可用实战方案

Nginx 作为当前最流行的 Web 服务器和反向代理之一,其负载均衡能力是构建高可用架构的关键组件。本文将从基础配置出发,逐步深入到权重分配、健康检查、会话保持和高可用方案,提供一套完整的 Nginx 负载均衡实战指南。

一、负载均衡基础配置

Nginx 通过 upstream 指令定义后端服务器组,配合 proxy_pass 实现请求转发。最基本的配置如下:

http {
    upstream backend {
        server 192.168.1.101:8080;
        server 192.168.1.102:8080;
        server 192.168.1.103:8080;
    }

    server {
        listen 80;
        server_name api.example.com;

        location / {
            proxy_pass http://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;
        }
    }
}

默认情况下,Nginx 使用轮询(Round Robin)策略,将请求依次分配给每台后端服务器。这种策略适用于后端服务器性能相近的场景。

二、负载均衡策略详解

2.1 权重分配

当后端服务器硬件配置不同时,可以通过 weight 参数调整分配比例:

upstream backend {
    server 192.168.1.101:8080 weight=3;  # 高配机器
    server 192.168.1.102:8080 weight=2;  # 中配机器
    server 192.168.1.103:8080 weight=1;  # 低配机器
}

2.2 IP 哈希

当需要会话保持(Session Sticky)时,使用 ip_hash 策略可以将来自同一 IP 的请求始终路由到同一台后端服务器:

upstream backend {
    ip_hash;
    server 192.168.1.101:8080;
    server 192.168.1.102:8080;
}

2.3 最少连接数

least_conn 策略将请求分配给当前连接数最少的服务器,适用于请求处理时间差异较大的场景:

upstream backend {
    least_conn;
    server 192.168.1.101:8080;
    server 192.168.1.102:8080;
}

2.4 一致性哈希

使用第三方模块 ngx_http_upstream_consistent_hash 可以实现一致性哈希,在节点增减时最小化缓存失效范围:

upstream backend {
    consistent_hash $request_uri;
    server 192.168.1.101:8080;
    server 192.168.1.102:8080;
    server 192.168.1.103:8080;
}

三、健康检查机制

3.1 被动健康检查

Nginx 开源版自带被动健康检查。通过 max_fails 和 fail_timeout 参数配置,当某台服务器在 fail_timeout 时间内失败次数达到 max_fails,将被临时剔除:

upstream backend {
    server 192.168.1.101:8080 max_fails=3 fail_timeout=30s;
    server 192.168.1.102:8080 max_fails=3 fail_timeout=30s;
    server 192.168.1.103:8080 max_fails=3 fail_timeout=30s backup;
}

其中 backup 参数标记的服务器作为备用节点,仅当所有主节点都不可用时才会启用。

3.2 主动健康检查

Nginx Plus 或使用第三方模块 nginx_upstream_check_module 可以实现主动健康检查,定期探测后端服务状态:

upstream backend {
    server 192.168.1.101:8080;
    server 192.168.1.102:8080;

    check interval=3000 rise=2 fall=3 timeout=2000 type=http;
    check_http_send "HEAD /health HTTP/1.0\r\n\r\n";
    check_http_expect_alive http_2xx http_3xx;
}

四、连接优化与性能调优

合理的连接参数配置可以显著提升 Nginx 的转发性能:

upstream backend {
    server 192.168.1.101:8080;
    server 192.168.1.102:8080;

    keepalive 32;           # 保持32个空闲连接
    keepalive_timeout 60s;  # 空闲连接超时时间
    keepalive_requests 1000; # 每个连接最大请求数
}

server {
    location / {
        proxy_pass http://backend;
        proxy_http_version 1.1;           # 启用HTTP/1.1以支持keepalive
        proxy_set_header Connection "";    # 清除Connection头

        proxy_connect_timeout 5s;    # 连接超时
        proxy_send_timeout 30s;      # 发送超时
        proxy_read_timeout 30s;      # 读取超时
        proxy_buffering on;          # 开启缓冲
        proxy_buffer_size 4k;
        proxy_buffers 8 4k;
    }
}

keepalive 参数让 Nginx 与后端服务器之间保持长连接,避免频繁的三次握手开销,在 QPS 较高的场景下效果尤为明显。

五、高可用方案:Keepalived + Nginx

单台 Nginx 本身就是单点故障。通过 Keepalived 实现 Nginx 的主备高可用是业界通用方案:

# /etc/keepalived/keepalived.conf(主节点)
vrrp_script chk_nginx {
    script "/etc/keepalived/check_nginx.sh"
    interval 2
    weight -20
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1

    authentication {
        auth_type PASS
        auth_pass YourSecret
    }

    virtual_ipaddress {
        192.168.1.100
    }

    track_script {
        chk_nginx
    }
}

检查脚本 check_nginx.sh 负责检测 Nginx 进程是否存活,一旦检测失败,Keepalived 会将 VIP 漂移到备用节点,实现自动故障切换。

#!/bin/bash
if ! pidof nginx > /dev/null; then
    systemctl restart nginx
    sleep 2
    if ! pidof nginx > /dev/null; then
        systemctl stop keepalived
    fi
fi

六、SSL 终结与安全加固

在负载均衡层统一处理 SSL 证书,可以减轻后端服务器的加解密负担:

server {
    listen 443 ssl http2;
    server_name api.example.com;

    ssl_certificate /etc/nginx/ssl/cert.pem;
    ssl_certificate_key /etc/nginx/ssl/key.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;

    location / {
        proxy_pass http://backend;
        proxy_set_header X-Forwarded-Proto https;
    }
}

七、日志与监控

配置详细的访问日志和错误日志,便于问题排查和性能分析:

log_format upstream_info '$remote_addr - $remote_user [$time_local] '
    '"$request" $status $body_bytes_sent '
    '"$http_referer" "$http_user_agent" '
    'upstream: $upstream_addr '
    'response_time: $upstream_response_time '
    'request_time: $request_time';

access_log /var/log/nginx/access.log upstream_info;

通过记录 upstream_addr、upstream_response_time 等信息,可以清晰地看到每个请求被转发到了哪台后端服务器以及响应耗时,对排查慢请求和定位故障节点非常有帮助。

总结

Nginx 负载均衡配置看似简单,但要构建一套生产级的高可用方案,需要综合考虑负载策略选择、健康检查机制、连接复用优化、高可用容灾和安全加固等多个方面。建议在实际部署中先搭建测试环境验证配置,再逐步推到生产,并配合完善的监控告警体系,确保系统在流量波动和节点故障时仍能稳定运行。