Nginx负载均衡 动态分离

第一部分:负载均衡基础理论

1. 四层、七层负载均衡(OSI 七层模型)

1)四层负载均衡(传输层 TCP/UDP,OSI 第 4 层)

  • 仅识别:源 IP、目标 IP、源端口、目标端口,看不到 HTTP 报文内容
  • 转发依据:只靠 IP + 端口分发 TCP/UDP 数据包
  • 优势:内核转发、性能极高;局限:无法区分域名、URL、Cookie
  • 适用:数据库、FTP、TCP 长连接服务

2)七层负载均衡(应用层 HTTP/HTTPS,OSI 第 7 层)

  • 完整解析 HTTP 请求报文
  • 转发依据:IP、端口、域名、URI、请求头、Cookie、接口参数
  • 优势:调度策略丰富、业务精细化分流;局限:性能弱于四层
  • 适用:网站 Web、前后端接口业务

2. 主流负载均衡产品

开源免费软件
  • Nginx:原生七层 Web 负载均衡;1.9 + 版本通过stream模块支持四层 TCP 负载
  • LVS:纯四层负载均衡,内核转发,吞吐性能天花板
  • HAProxy:同时完整支持四层 TCP、七层 HTTP,Web / 数据库通用
商业硬件(企业付费)

F5、Netscaler、Radware、A10 特点:可视化管理、自带 WAF 防护、厂商 7*24 技术支持,成本高昂

3. Nginx 后端节点健康检查机制

Nginx upstream 仅提供被动健康检查

  1. 后端节点连续请求超时 / 连接失败,临时剔除故障节点,不再分配流量
  2. 故障节点恢复后,自动重新加入集群参与调度
  3. 缺陷:无内置短信 / 邮件告警,需搭配 Zabbix/Prometheus 监控实现故障提醒

4. 五大负载均衡调度算法

表格

算法 全称 调度规则 适用场景
rr 轮询(默认) 请求按顺序轮流分配给所有后端 所有服务器硬件性能完全一致
wrr 权重轮询 weight=数字,数值越大承载流量越多 服务器配置高低不均,高配多分担流量
ip_hash 源 IP 哈希调度 同一客户端 IP 固定访问同一台后端 会话保持,解决 Web Session 丢失问题
least_conn 最小连接数 新请求优先分给当前并发最少的节点 上传、大文件等长耗时业务
fair 响应时间调度 后端响应越快,分配流量越多 后端负载波动大(需第三方模块编译)

第二部分:环境规划

集群机器分工

  1. LB 负载均衡网关(Nginx 七层代理):192.168.233.160
  2. web01 后端业务节点:192.168.233.150:80
  3. web02 后端业务节点:192.168.233.162:80
  4. NFS 共享存储服务端:192.168.233.200,所有机器挂载目录/data/nfs

需求

  1. LB 实现负载均衡分发流量至 web01、web02
  2. 日志格式区分 LB 本机 IP、真实访客客户端 IP
  3. 完整动静分离架构:静态资源直读 NFS、动态业务转发 web 集群
  4. 上传文件区分 POST 写入、GET 读取两种逻辑;支付接口独立分流

第三部分:LB 网关完整 Nginx 配置(带逐行注释)

nginx

复制代码
# 全局工作进程,建议设为CPU核心数
worker_processes  1;

# 事件模块:控制单个进程最大并发连接数量
events {
    worker_connections  1024;
}

# HTTP七层核心模块,实现反向代理、负载均衡、动静分离
http {
    # 引入mime文件,识别html/css/js/png/mp4等资源类型
    include       mime.types;
    default_type  application/octet-stream;

    # 自定义日志格式:打印LB网关IP + 真实访客IP
    log_format access_show_ip 
    '$remote_addr - $remote_user [$time_local] "$request" '
    '$status $body_bytes_sent "$http_referer" "$http_user_agent" '
    '【LB网关本机IP:$remote_addr】 【真实访客客户端IP:$http_x_forwarded_for】';
    # 指定日志存储路径,启用自定义日志模板
    access_log  logs/lb_access.log  access_show_ip;

    sendfile        on;        # 开启零拷贝,优化静态文件磁盘IO
    keepalive_timeout  65;      # HTTP长连接超时65秒
    gzip on;                    # 开启资源压缩,减小网络传输体积
    # 指定需要压缩的静态文件类型
    gzip_types text/css text/javascript image/png image/jpeg image/mp4;

    # 定义后端业务地址池:包含web01、web02两台节点
    upstream dynamic_server_group {
        # ip_hash;        # 取消注释开启会话保持
        # least_conn;     # 取消注释开启最小连接调度
        server 192.168.233.150:80 weight=1; # web01 权重1
        server 192.168.233.162:80 weight=1; # web02 权重1
        # server 192.168.233.163:80 backup;  # 备用节点,主节点全故障才启用
    }

    # 对外访问虚拟主机,绑定业务域名
    server {
        listen 80;
        server_name www.web-test.com;

        # 统一向后端传递客户端原始信息,web01/web02日志可拿到真实访客IP
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;

        # 分支1:/static 纯静态资源(js/css/字体/图标),直接读取NFS,不走后端
        location /static/ {
            root /data/nfs;       # NFS共享挂载目录
            expires 7d;           # 浏览器本地缓存7天,减少重复请求
            add_header Cache-Control "public";
        }

        # 分支2-1:GET请求拉取/upload下图片/视频,LB直读NFS返回,无需后端处理
        location ~* ^/upload/.*\.(png|jpg|jpeg|mp4|mp3)$ {
            root /data/nfs;
            expires 3d; # 图片视频缓存3天
        }

        # 分支2-2:POST上传文件请求,转发web集群写入NFS并更新数据库
        location /upload/ {
            proxy_pass http://dynamic_server_group;
            client_max_body_size 50M; # 限制单文件最大50MB,防止大文件攻击
        }

        # 分支3:/pay 支付专属接口,独立转发后端,业务解耦可单独限流防护
        location /pay/ {
            proxy_pass http://dynamic_server_group;
        }

        # 分支4:首页、商品列表等通用动态页面,全部转发web集群
        location / {
            proxy_pass http://dynamic_server_group;
        }
    }
}

第四部分:web01、web02 后端节点统一配置(两台配置完全一致)

两台后端仅处理动态业务(Java/PHP),静态资源统一由 LB 直读 NFS,后端无需存放图片、js、css

nginx

复制代码
worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    # 后端日志打印经过LB传递的真实客户端IP
    log_format web_real_ip '$http_x_forwarded_for - $remote_user [$time_local] "$request" $status';
    access_log  logs/web_access.log web_real_ip;

    sendfile        on;
    keepalive_timeout  65;

    server {
        listen 80;
        server_name www.web-test.com;

        # 处理首页、上传、支付动态逻辑(Java/PHP程序目录)
        root html;
        index index.html index.htm index.php;

        # 动态程序转发(示例PHP-FPM,Java替换为proxy_pass tomcat地址)
        location ~ \.php$ {
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;
        }
    }
}

第五部分:全链路动静分离业务架构解读

1. 完整请求流程

客户端访问域名 → 请求抵达 LB 网关 → Nginx 按 URL 路径分流:

  1. /static / 图片 GET 请求:LB 直接读取 NFS 静态文件返回浏览器,不经过 web01/web02
  2. /upload POST 上传 / /pay / 首页:转发至 web01/web02 动态集群处理业务逻辑

2. 四大流量分支业务逻辑

1)/upload 文件上传分支

  • POST 上传:web 后端接收文件 → 写入共享 NFS /data/nfs/upload → 数据库资源表记录文件名、存储路径、用户 ID
  • GET 图片访问:LB 直接读取 NFS 图片返回,不消耗后端程序资源

2)/ 首页 / 列表动态读分支

  • 请求转发 web 后端,后端查询「用户表」「资源表」拿到图片路径
  • 页面拼接图片 URL,前端再次发起静态资源请求,由 LB 直接返回图片

3)/static 纯静态资源分支 无需后端、无需数据库,LB 直接响应,开启浏览器长期缓存,大幅降低集群压力

4)/pay 支付接口分支 独立转发 web 集群,和普通页面业务隔离,可单独配置限流、WAF 安全策略

3. 数据库两张核心业务表

  1. 用户表:存储用户名、密码、头像、个人资料等基础用户数据
  2. 资源表:存储上传文件名、NFS 文件存储路径,页面渲染时读取路径展示图片

4. NFS 共享存储作用

LB、web01、web02 全部统一挂载同一 NFS 目录 /data/nfs 任意一台机器上传的文件,全集群均可访问,解决多后端服务器本地文件不同步问题

5. 动静分离架构四大优势

  1. 性能隔离:静态资源全部由 LB 处理,Java/PHP 后端只负责数据库交互,并发承载能力翻倍提升
  2. 业务解耦:支付、上传、首页流量拆分,支付业务可单独扩容、限流、安全防护,互不干扰
  3. 文件统一管理:NFS 集中存储所有图片视频,后端无需同步本地文件,数据库仅记录路径即可
  4. 缓存降载:静态资源开启浏览器缓存,大量重复静态请求在客户端直接命中,减少网关、后端、数据库压力

第六部分:配套运维操作命令

1. 所有机器统一挂载 NFS 共享存储

bash

运行

复制代码
# NFS服务端IP:192.168.233.200,共享目录/nfs_share,本机挂载点/data/nfs
mount 192.168.233.200:/nfs_share /data/nfs

2. Nginx 配置校验 + 平滑重载(源码安装通用)

bash

运行

复制代码
# 校验配置语法,报错直接提示错误行数
/usr/local/nginx/sbin/nginx -t
# 平滑重载,不中断在线用户访问
/usr/local/nginx/sbin/nginx -s reload

3. 流量访问验证区分

  1. curl www.web-test.com/static/js/main.js:仅 LB 生成日志,web01/web02 无访问记录(纯静态直读 NFS)
  2. curl -X POST www.web-test.com/upload:流量转发 web01/web02,后端执行写入 NFS、更新数据库
  3. curl www.web-test.com/upload/1.png:LB 直接读取 NFS 图片,后端无日志
  4. curl www.web-test.com/pay/order:转发后端支付业务,操作订单数据库

4. 循环测试负载均衡分发

bash

运行

复制代码
# 连续10次访问,观察日志流量交替打到web01、web02
for i in `seq 1 10`;do curl www.web-test.com;echo "";sleep 0.5;done