nginx负载均衡

硬件环境与架构设计

角色主机名IP地址操作系统核心软件
负载均衡器 lb-server 10.196.1.100 Ubuntu 22.04 Nginx
后端应用节点1 app-server1 10.196.1.101 Ubuntu 22.04 Nginx, PHP-FPM, MySQL
后端应用节点2 app-server2 10.196.1.102 Ubuntu 22.04 Nginx, PHP-FPM, MySQL
后端应用节点3 app-server3 10.196.1.103 Ubuntu 22.04 Nginx, PHP-FPM, MySQL (高可用部署用)
数据库节点 db-server 10.196.1.200 Ubuntu 22.04 MySQL (主库)
高可用节点1(备) ha-peer1 10.196.1.201 Ubuntu 22.04 Keepalived
高可用节点2(备) ha-peer2 10.196.1.202 Ubuntu 22.04 Keepalived

服务架构图

负载均衡

 

 

核心配置路径

1. 负载均衡器配置

在负载均衡器 lb-server 上,Nginx的核心工作是通过 upstream 模块定义后端服务器池,并通过 server 块接收并转发请求。

  • 配置文件: /etc/nginx/conf.d/loadbalance.conf

# 定义后端服务器组,名为 'php_backend'
upstream php_backend {
    # 启用最少连接数算法,适合长连接或请求处理时间不均的场景
    least_conn;

    # server 配置说明:
    # weight=3: 权重为3,处理能力更强的服务器分配更高权重
    # max_fails=3: 在 fail_timeout 时间内最多允许失败3次
    # fail_timeout=30s: 当失败次数达到 max_fails 后,认定服务器不可用,并在30秒内不再分发请求
    server 10.168.1.101:80 weight=3 max_fails=3 fail_timeout=30s;
    server 10.168.1.102:80 weight=2 max_fails=3 fail_timeout=30s;
    server 10.168.1.103:80 weight=1 max_fails=3 fail_timeout=30s backup; # backup 作为备用
    
    # 保持长连接,减少与后端建立连接的开销
    keepalive 32;
}

server {
    listen 80;
    server_name yourdomain.com; # 替换为你的域名或负载均衡器IP

    # 关键请求头设置,用于向后端传递真实客户端信息
    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;

    # 启用 HTTP 1.1 并清除 Connection 头,以支持与后端的 keepalive
    proxy_http_version 1.1;
    proxy_set_header Connection "";

    location / {
        # 将请求代理到上面定义的 php_backend 组
        proxy_pass http://php_backend;
        
        # 设置超时,防止慢响应拖垮系统
        proxy_connect_timeout 5s;
        proxy_read_timeout 60s;
    }

    # 静态文件直接由Nginx处理或代理到专门的静态服务器实现动静分离
    location ~* \.(jpg|png|css|js|ico)$ {
        proxy_pass http://static_servers;
        expires 30d;
    }
}

后端应用节点配置

每个后端节点上的Nginx配置,其主要作用是与本地的PHP-FPM进程通信,处理动态请求。为保证各节点配置统一,需要考虑文件同步机制。

  • 配置文件: /etc/nginx/sites-available/yourdomain.com

server {
    listen 80;
    server_name yourdomain.com; # 与负载均衡器的 server_name 保持一致
    root /var/www/yourdomain/public; # 项目的入口目录

    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        # 与本地 PHP-FPM 进程通信,通常使用 Unix Socket
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.ht {
        deny all;
    }
}

说明: 核心是 fastcgi_pass unix:/var/run/php/php8.1-fpm.sock; 指令,它将PHP请求交由本地的PHP-FPM处理

3. 防御体系构建

  • 防火墙: 使用 ufw 或 firewalld,仅开放必要的端口。负载均衡器需开放 80/443,后端节点仅对负载均衡器开放 80、9000等端口。

  • SSL证书: 通常统一在负载均衡器上配置,使用 Let's Encrypt 等工具即可,无需在各后端节点重复配置。

  • 会话保持: 推荐使用 Redis 等集中式存储来共享Session,这是更具扩展性的解决方案。ip_hash 算法可作为临时方案,但在服务器扩缩容时会导致大量会话中断。


四、测试与验证

配置完成后,务必进行测试以确保配置无误:

  1. 配置语法检查: sudo nginx -t

    • 输出应包含 syntax is ok 和 test is successful

  2. 重载Nginx: sudo systemctl reload nginx

    • 此操作可保证服务不中断地应用新配置。

  3. 功能验证:

    • 在浏览器中访问负载均衡器的IP或域名。

    • 在各后端节点上执行 tail -f /var/log/nginx/access.log,观察请求是否被均匀分发。

  4. 故障模拟:

    • 停止某一台后端节点的Nginx服务: sudo systemctl stop nginx

    • 访问负载均衡器,验证请求是否能自动转发到其他健康节点。

  5. 压力测试:

    • 使用 ab(Apache Benchmark)进行简单的压测。

    bash
    ab -n 10000 -c 100 http://yourdomain.com/
    • 通过分析报告中的 Failed requests 数量和 Requests per second 值,初步评估性能。


五、验收标准

 
 
检查项验收标准
功能完整性 通过负载均衡器IP/域名能正常访问业务,所有接口和功能符合预期。
负载分发 请求能按照配置的算法(如权重、最少连接数)均匀分发到各后端节点。
高可用性 任意一台后端节点故障时,服务不受影响。负载均衡器单点故障时,备用节点能自动接管服务。
Session 共享 用户登录状态在任意节点间保持一致。
动静分离 静态资源由Nginx高效处理,响应头包含正确的 Cache-Control 信息。
性能基准 在预期并发下,系统平均响应时间和错误率在可接受范围内(如P99 < 500ms,错误率<0.1%)。
安全性 非必要端口未对外开放,HTTPS配置正确,无安全漏洞报告。

 

六、Nginx多种配置策略以及对应示例

静态策略(不感知后端状态:)

  • rr(轮询,默认): 请求按时间顺序逐一分配到不同后端服务器。适用于后端性能一致的场景。原理:按顺序轮流分发,循环往复;特点:简单,公平,适合后端性能一致的无状态服务;缺点:不关心后端负载,慢节点会挤压请求

#轮询示例:
upstream backend_rr {
    # 默认轮询,无需额外指令
    server 10.168.1.101:80;
    server 10.168.1.102:80;
    server 10.168.1.103:80;
}

server {
    location / {
        proxy_pass http://backend_rr;
    }
}
  • wrr(加权轮询): 在轮询基础上增加权重,权重高的服务器被分配更多请求。适用于后端性能不均的情况。原理:为每台服务增加权重,权重越高请求越多;特点:适配异构集群;

#加权轮询示例
upstream backend_wrr {
    server 10.168.1.101:80 weight=5;   # 性能强的节点
    server 10.168.1.102:80 weight=3;
    server 10.168.1.103:80 weight=1;   # 性能较弱的节点
}

server {
    location / {
        proxy_pass http://backend_wrr;
    }
}
  • ip_hash: 对客户端 IP 进行哈希计算,确保同一 IP 的请求固定发往同一台后端服务器。主要用于解决 Session 问题(实现简单的会话保持)。原理:对客户端IP进行hash计算,请求落到固定某台服务器;特点:实现会话时保持,无需共享session;缺点:IP变化会导致会话丢失;若某个节点故障,该节点上的全部用户都会收到影响;可能导致某个负载不均(某个IP有大量的访问)

#IP_HASH示例
upstream backend_iphash {
    ip_hash;      # 基于客户端IPv4地址的前三个八位字节或整个IPv6地址做哈希
    server 10.168.1.101:80;
    server 10.168.1.102:80;
    # 若某节点需要下线维护,可用 down 参数
    # server 10.168.1.103:80 down;
}

server {
    location / {
        proxy_pass http://backend_iphash;
    }
}
  • url_hash: 根据请求的 URL 进行哈希,常用于缓存服务器(如 Squid、Varnish)以提高缓存命中率。特点:根据请求的URL或部分路径做hash,相同url始终到同一台后端;用途:提高缓存命中率;缺点:热点URL会造成单节点压力
#URL 哈希示例
upstream backend_urlhash {
    # 对请求的完整 URI(包含参数)做哈希
    hash $request_uri consistent;   # consistent 开启一致性哈希特性
    server 10.168.1.101:80;
    server 10.168.1.102:80;
}

server {
    location / {
        proxy_pass http://backend_urlhash;
    }
}

动态策略(感知后端状态):

  • least_conn(最小连接数): 动态地选择当前活动连接数最少的后端服务器。适用于请求处理时间长短不一(如有的请求慢,有的快)的场景,能更均衡地利用后端资源。原理:分发到当前活动连接数最少的后端;优势:适合请求处理时间差异大的场景,能平衡实时负载

#最小链接数策略
upstream backend_lc {
    least_conn;   # 激活最少连接算法
    server 10.168.1.101:80;
    server 10.168.1.102:80;
    server 10.168.1.103:80;
}

server {
    location / {
        proxy_pass http://backend_lc;
    }
}
  • least_time(最短响应时间):原理:结合连接数和响应时间,选择响应最快且链接最少的节点;特点:对延迟敏感的服务最友好,但需要持续统计响应时间;

#响应时间最短示例
# Nginx Plus 专属配置
upstream backend_lt {
    least_time header;   # 或 last_byte(考虑接收完整响应的时间)
    server 10.168.1.101:80;
    server 10.168.1.102:80;
}

server {
    location / {
        proxy_pass http://backend_lt;
    }
}
  • random(随机): 原理:随机选择后端,可带权重;特点:适合大规模集群,配合概率分布可近似达到均衡,但一般不如轮询稳定

#随机示例
upstream backend_rand {
    random;            # 随机选择
    # 可结合权重:random two least_conn;  先从两个随机节点中选连接数最少的
    server 10.168.1.101:80;
    server 10.168.1.102:80 weight=2;  # 权重也会影响随机概率
}

server {
    location / {
        proxy_pass http://backend_rand;
    }
}

策略对比与选型建议

场景推荐策略原因
简单无状态 Web 服务 轮询 (加权轮询) 实现简单,公平分配。
后端性能差异大 加权轮询 手动分配权重,避免慢节点拖累。
请求处理时间差异大 最少连接 自动避免长连接堆积在某节点。
低延迟敏感型服务 最短响应时间 优先响应快的节点,降低整体延迟。
需要会话保持(无共享存储) IP Hash 或 一致性哈希(基于用户 ID) 保证同一用户固定到同一节点。
分布式缓存(Redis/Memcached) 一致性哈希 扩缩容时缓存命中率最高。
微服务网关 / API Gateway 最少连接 + 动态权重 需要感知下游服务健康状态和实时负载。
数据库连接池代理 最少连接 或 加权轮询 避免连接数不均
posted @ 2026-05-13 14:28  阿陌i  阅读(5)  评论(0)    收藏  举报