两台同地域服务器之间的负载均衡配置教程(基于 Nginx 通用方案)



一、架构概述与准备工作

本教程适用于任何云厂商(如腾讯云、阿里云、AWS、Azure、Google Cloud 等)或自建机房环境。架构包含 3 台处于同一内网/地域的 Linux 服务器:

  • 负载均衡器节点 (LB):内网 IP 为 192.168.1.100,用于接收请求并分发。
  • 后端应用服务器 A (Web-A):内网 IP 为 192.168.1.101。
  • 后端应用服务器 B (Web-B):内网 IP 为 192.168.1.102。

二、步骤一:配置后端 Web 服务器 (Web-A 与 Web-B)

分别登录到两台后端服务器,安装基础 Web 服务并设置测试响应页面:

1. 在 Web-A (192.168.1.101) 上配置

注:Debian/Ubuntu 环境使用 apt;CentOS/RHEL 环境请替换为 yum install -y nginx,默认路径为 /usr/share/nginx/html/index.html。

# 安装 Nginx 服务
sudo apt update && sudo apt install -y nginx

# 写入测试页面内容
echo "Response from Web Server A (192.168.1.101)" | sudo tee /var/www/html/index.html

# 启动并设置自启
sudo systemctl enable --now nginx

2. 在 Web-B (192.168.1.102) 上配置

# 安装 Nginx 服务
sudo apt update && sudo apt install -y nginx

# 写入测试页面内容
echo "Response from Web Server B (192.168.1.102)" | sudo tee /var/www/html/index.html

# 启动并设置自启
sudo systemctl enable --now nginx

三、步骤二:配置负载均衡服务器 (LB)

登录负载均衡节点 192.168.1.100,利用 Nginx 的 upstream 模块配置反向代理与流量分发规则。

1. 安装 Nginx 核心服务

sudo apt update && sudo apt install -y nginx

2. 修改 Nginx 配置文件

编辑 /etc/nginx/sites-available/default(CentOS 路径为 /etc/nginx/conf.d/loadbalancer.conf):

upstream my_backend_cluster {
    # 加权轮询算法(Weighted Round Robin)
    # 开源版被动健康检查:连续失败 3 次后,暂停向该节点转发 30 秒
    server 192.168.1.101:80 weight=1 max_fails=3 fail_timeout=30s;
    server 192.168.1.102:80 weight=1 max_fails=3 fail_timeout=30s;
}

server {
    listen 80;
    server_name _;

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

3. 检查配置并重启 Nginx 服务

# 检查配置文件语法
sudo nginx -t

# 重新加载配置生效
sudo systemctl reload nginx

四、步骤三:网络安全组与防火墙配置

确保网络层允许内网节点通信:

# 开放 80 端口(ufw 示例;CentOS 使用 firewall-cmd)
sudo ufw allow 80/tcp
sudo ufw reload

五、步骤四:验证负载均衡效果

发起并发请求验证轮询效果:

curl http://192.168.1.100/
curl http://192.168.1.100/

预期交替返回以下响应:

Response from Web Server A (192.168.1.101)
Response from Web Server B (192.168.1.102)

六、主动健康检查与 OpenResty 编译部署

1. 被动检查的机制限制

开源版 Nginx 的被动健康检查仅在 HTTP 请求产生错误响应或超时后触发计数。在低流量或离线时段,节点发生物理中断时 Nginx 无法感知状态变更,导致恢复后的初始请求产生阻塞或报错。

2. OpenResty 编译 `nginx_upstream_check_module`

第一步:安装依赖与源码准备

sudo apt update && sudo apt install -y build-essential libpcre3-dev zlib1g-dev libssl-dev git wget

cd /usr/local/src
git clone https://github.com/yaoweibin/nginx_upstream_check_module.git

wget https://openresty.org/download/openresty-1.21.4.1.tar.gz
tar -zxvf openresty-1.21.4.1.tar.gz
cd openresty-1.21.4.1/bundle/nginx-1.21.4

patch -p1 < /usr/local/src/nginx_upstream_check_module/check_1.20.1+.patch

第二步:编译安装

cd /usr/local/src/openresty-1.21.4.1
./configure \
    --prefix=/usr/local/openresty \
    --add-module=/usr/local/src/nginx_upstream_check_module

make -j$(nproc)
sudo make install

第三步:配置主动心跳探测

编辑 /usr/local/openresty/nginx/conf/nginx.conf:

http {
    upstream my_backend_cluster {
        server 192.168.1.101:80 weight=1;
        server 192.168.1.102:80 weight=1;

        # 主动探测参数:每 3000ms 发送一次 HTTP 探针,连续失败 3 次剔除,连续成功 2 次上线
        check interval=3000 rise=2 fall=3 timeout=1000 type=http;
        check_http_send "GET /health HTTP/1.0\r\nHost: localhost\r\n\r\n";
        check_http_expect_alive http_2xx http_3xx;
    }

    server {
        listen 80;
        server_name _;

        location / {
            proxy_pass http://my_backend_cluster;
        }

        location /status {
            check_status;
            access_log off;
        }
    }
}

七、`proxy_next_upstream` 幂等性行为压测分析

1. 测试配置与环境说明

后端集群包含正常节点 192.168.1.101:80 (返回 200) 与故障节点 192.168.1.102:80 (返回 503):

upstream backend_test {
    server 192.168.1.101:80;
    server 192.168.1.102:80;
}

server {
    listen 80;
    location /api {
        proxy_pass http://backend_test;
        proxy_next_upstream error timeout http_503;
        proxy_next_upstream_tries 2;
    }
}

2. 不同请求方法的并发测试数据

GET 请求(幂等方法)测试命令及输出:

ab -n 100 -c 10 http://192.168.1.100/api

Complete requests:      100
Failed requests:        0
Non-2xx responses:      0

分析:GET 请求符合 RFC 7231 幂等规范,命中 503 后自动触发重试,无失败响应。

POST 请求(非幂等方法,未配置 `non_idempotent`)测试命令及输出:

ab -n 100 -c 10 -p post_data.json -T "application/json" http://192.168.1.100/api

Complete requests:      100
Failed requests:        50
Non-2xx responses:      50  (HTTP/1.1 503 Service Unavailable)

分析:Nginx 默认阻止非幂等请求(POST/PATCH 等)的自动重试,故障节点的 503 响应直接透传给客户端,失败率约为 50%。

POST 请求(配置 `non_idempotent`)测试输出:

修改配置为 proxy_next_upstream error timeout http_503 non_idempotent; 后执行同等测试:

Complete requests:      100
Failed requests:        0
Non-2xx responses:      0

八、L4 (IPVS/DR 模式) 与 L7 (Nginx) 联动收敛演练日志

架构为 IPVS/DR 模式挂载 10.0.1.10 (L7-A) 与 10.0.1.11 (L7-B)。探针配置为 interval=3000ms, fall=2。以下为中断 L7-A 进程时的网络层记录:

[2026-10-22 10:00:00.000] [INFO] IPVS 按照 RR 算法分发 TCP SYN 至 10.0.1.10 与 10.0.1.11
[2026-10-22 10:00:05.120] [ACTION] 在 10.0.1.10 执行 `pkill -9 nginx`

[2026-10-22 10:00:05.122] [L4 Traffic] IPVS 持续向 10.0.1.10 改写 MAC 并转发 SYN 报文
[2026-10-22 10:00:05.123] [L7 Kernel] 10.0.1.10 内核协议栈向客户端直接回应 TCP RST 报文
[2026-10-22 10:00:05.125] [Client Side] 客户端应用层捕获 Connection Refused 错误,触发客户端连接池/协议栈重试机制

[2026-10-22 10:00:06.000] [L4 Probe] L4 探针检测到 10.0.1.10:80 返回 RST (失败计数: 1/2)
[2026-10-22 10:00:09.000] [L4 Probe] L4 探针检测到 10.0.1.10:80 返回 RST (失败计数: 2/2)
[2026-10-22 10:00:09.001] [L4 Action] IPVS 控制面将 10.0.1.10 权重置 0 (Weight=0) 并剔除出转发表
                         【收敛结果】:容错窗口长度为 3.88 秒(从 10:00:05.120 至 10:00:09.001)。期间共有 24 个新 SYN 请求收到 RST 并依赖客户端重试机制恢复。

[2026-10-22 10:00:20.000] [ACTION] 执行 `systemctl start nginx` 恢复 10.0.1.10
[2026-10-22 10:00:21.000] [L4 Probe] L4 探针检测到 10.0.1.10:80 返回 SYN-ACK (成功计数: 1/2)
[2026-10-22 10:00:24.000] [L4 Probe] L4 探针检测到 10.0.1.10:80 返回 SYN-ACK (成功计数: 2/2)
[2026-10-22 10:00:24.002] [L4 Action] 重新恢复 10.0.1.10 转发权重

九、负载均衡技术选型与机制限制

技术组件 适用的架构场景 机制限制与反模式 (Anti-Pattern)
LVS (DR 模式) 自建物理机房、追求极高网卡吞吐且避开负载均衡器回包瓶颈的场景。 不支持公有云 VPC 环境(无法直接改写二层 MAC 地址);要求 Real Server 与 LVS 必须处于同一二层广播域(不可跨三层路由器)。
DPDK 自研网关 超大规模入口、需在网卡用户态直接处理数 Gbps 级线速报文及 DDoS 防御。 DPDK 采用 UIO/VFIO 绕过内核协议栈在用户态接管网卡,缺乏内核级崩溃隔离保护机制。应用层代码发生 Memory Corruption 或空指针异常时,会导致网卡驱动与进程同步崩溃,风险高于内核态模块。
OpenResty (Nginx + Lua) 需动态修改 Upstream、复杂限流防刷、自定义 Token 鉴权的 API 网关。 在 Lua 代码中使用阻塞式 I/O 命令(如标准 LuaSocket 或同步阻塞数据库驱动),这会导致 Nginx 的单线程 Worker 进程挂起,阻塞 Event Loop 处理。
Envoy Kubernetes 容器环境与微服务 Service Mesh 动态 xDS 热更新场景。 静态物理机部署。Envoy 的配置模型高度抽象且静态 YAML 编写繁琐,调试与内存泄漏排查成本显著高于 Nginx。
VRRP (Keepalived) 物理机房内使用 Gratuitous ARP 实现双机 VIP 漂移。 公有云 SDN 环境(组播和广播被禁用,免费 ARP 受到限制)。云上环境须使用云厂商 HAVIP 或 OpenAPI 实现地址漂移。



粤ICP备2026163276号