Nginx反向代理与负载均衡实战指南

Nginx 反向代理与负载均衡实战指南

Nginx 是 Web 架构中的"万能胶水":反向代理、负载均衡、静态资源、HTTPS、限流、缓存、灰度发布,一个它全包了。本文从安装配置讲起,覆盖反向代理、负载均衡、动静分离、HTTPS、限流、常见坑,全程带配置,可直接抄。


一、Nginx 是什么

1.1 三种典型角色

Web 服务器:托管静态资源(HTML、JS、图片)------比 Tomcat 快几个数量级。

反向代理:接收外部请求,转发给内部后端(Tomcat、Spring Boot)。

复制代码
用户 → Nginx(80) → 后端应用(8080)

负载均衡:多个后端实例,Nginx 按策略分发。

复制代码
用户 → Nginx(80) → app1:8080
                  → app2:8080
                  → app3:8080

1.2 为什么用 Nginx

  • 高并发:事件驱动,单机 5-10 万并发(Apache 同期只有几千);
  • 稳定:内存占用小、久跑不掉;
  • 灵活:配置热加载(reload 不中断服务);
  • 生态:HTTP/2、HTTPS、WebSocket、限流、缓存全套。

二、安装与基本配置

2.1 安装

bash 复制代码
# CentOS
yum install -y nginx
# Ubuntu
apt install -y nginx
# 或编译安装(要自定义模块时)

Docker 方式:

bash 复制代码
docker run -d --name nginx -p 80:80 -v /data/nginx:/etc/nginx nginx:1.25

2.2 配置文件结构

复制代码
/etc/nginx/
├── nginx.conf          # 主配置
├── conf.d/             # 子配置(include)
└── sites-enabled/      # 站点配置
nginx 复制代码
# nginx.conf 主结构
user  nginx;
worker_processes  auto;          # 和 CPU 核数一致

events {
    worker_connections  10240;   # 每个 worker 最大连接数
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

    # 引入站点配置(推荐把每个站点写一个文件)
    include /etc/nginx/conf.d/*.conf;
}

2.3 基本命令

bash 复制代码
nginx -t                 # 测试配置语法(改完必跑)
nginx -s reload          # 热加载(不中断)
nginx -s stop            # 停止
systemctl start nginx    # 启动服务
systemctl status nginx

红线 :改配置先 nginx -t,通过再 reload。


三、反向代理配置

3.1 最简单代理

nginx 复制代码
server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://127.0.0.1:8080;
        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_pass:后端地址;
  • 三个 proxy_set_header:必须,否则后端拿不到真实 IP;
  • $host:请求的域名;
  • $remote_addr:客户端 IP。

3.2 按路径分发(网关雏形)

nginx 复制代码
server {
    listen 80;
    server_name mall.example.com;

    location /api/user/ {
        proxy_pass http://user-service:8081/;   # 注意末尾斜杠
    }
    location /api/order/ {
        proxy_pass http://order-service:8082/;
    }
    location / {
        proxy_pass http://frontend:80/;
    }
}

斜杠陷阱:

  • proxy_pass http://backend/(带斜杠):把 location 前缀替换为 /;
  • proxy_pass http://backend(不带斜杠):原样传递完整 URI。

3.3 WebSocket 代理

nginx 复制代码
location /ws/ {
    proxy_pass http://ws-service:9000/;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_read_timeout 3600s;   # 长连接别超时
}

四、负载均衡

4.1 upstream 配置

nginx 复制代码
upstream backend {
    server 192.168.1.10:8080 weight=3;   # 权重 3
    server 192.168.1.11:8080 weight=1;   # 权重 1
    server 192.168.1.12:8080 down;       # 标记下线(维护)
}

server {
    listen 80;
    location / {
        proxy_pass http://backend;
    }
}

4.2 负载均衡策略

策略 配置 特点
轮询 默认 平均分发,无权重
权重 weight=3 按比例分发(性能不均时用)
IP 哈希 ip_hash; 同一 IP 固定到同一后端(Session 亲和)
最少连接 least_conn; 分给连接数最少的后端
一致性哈希 hash $request_uri; 按 key 分配(缓存友好)

Session 问题:无状态服务(JWT)无所谓;有状态 Session 用 ip_hash 或把 Session 挪到 Redis。

4.3 健康检查

nginx 复制代码
upstream backend {
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;

    # 主动健康检查(开源版需要第三方模块,商业版/OpenResty 内置)
    check interval=5000 rise=2 fall=3 timeout=2000;
}

被动检查:默认配置下,后端挂了 Nginx 会自动摘除(连接失败后),恢复后自动加回。

4.4 实战:Spring Boot 集群

复制代码
架构:
用户 → Nginx(80) → app1:8080 / app2:8080
                       ↓ 共享
                  MySQL + Redis
nginx 复制代码
upstream app_cluster {
    least_conn;
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;
    server 192.168.1.12:8080 backup;   # 备用节点
}

五、动静分离

5.1 为什么动静分离

静态资源(JS/CSS/图片)让 Nginx 直接返回(几微秒),别让 Java 应用处理(还要起线程)。

nginx 复制代码
server {
    listen 80;
    server_name www.example.com;

    # 静态资源:Nginx 直接返回
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2)$ {
        root /data/frontend/dist;
        expires 7d;                 # 浏览器缓存 7 天
        add_header Cache-Control "public, max-age=604800";
    }

    # 前端页面
    location / {
        root /data/frontend/dist;
        index index.html;
        try_files $uri $uri/ /index.html;   # 前端路由 history 模式必配
    }

    # 后端接口
    location /api/ {
        proxy_pass http://backend;
    }
}

5.2 前端 history 路由 404 问题

Vue/React 用 history 模式路由,刷新 /user/123 时 Nginx 找不到文件------用 try_files 兜底到 index.html。

nginx 复制代码
location / {
    try_files $uri $uri/ /index.html;
}

六、HTTPS 配置

6.1 申请证书

bash 复制代码
# certbot 免费证书
apt install certbot python3-certbot-nginx
certbot --nginx -d example.com -d www.example.com

或云厂商(阿里云/腾讯云)免费证书。

6.2 配置 HTTPS

nginx 复制代码
server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate     /etc/nginx/cert/example.com.pem;
    ssl_certificate_key /etc/nginx/cert/example.com.key;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_session_cache shared:SSL:10m;

    location / {
        proxy_pass http://backend;
    }
}

# HTTP 跳转 HTTPS
server {
    listen 80;
    server_name example.com;
    return 301 https://$host$request_uri;
}

6.3 混合 HTTP/HTTPS

坑:HTTPS 页面里请求 HTTP 接口,浏览器拦截(Mixed Content)。要么全站 HTTPS,要么后端接口也走 HTTPS。


七、限流与安全

7.1 限流

nginx 复制代码
# 定义限流区:rate 10r/s = 每秒 10 个请求
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;

server {
    location /api/ {
        limit_req zone=api_limit burst=20 nodelay;  # 突发 20 个
        proxy_pass http://backend;
    }
}

参数:

  • rate=10r/s:平均速率;
  • burst=20:突发缓冲 20 个(排队);
  • nodelay:突发请求立即处理(不排队)。

7.2 连接数限制

nginx 复制代码
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;

location /download/ {
    limit_conn conn_limit 10;   # 同一 IP 最多 10 并发连接
}

7.3 安全头

nginx 复制代码
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options SAMEORIGIN;
add_header X-XSS-Protection "1; mode=block";

7.4 隐藏版本号

nginx 复制代码
server_tokens off;

八、缓存

8.1 静态资源缓存(浏览器端)

nginx 复制代码
location ~* \.(js|css|png)$ {
    expires 30d;
}

8.2 代理缓存(后端响应缓存)

nginx 复制代码
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=cache_zone:100m max_size=10g inactive=60m;

location /api/ {
    proxy_cache cache_zone;
    proxy_cache_valid 200 10m;      # 200 响应缓存 10 分钟
    proxy_cache_key "$scheme$host$request_uri";
    add_header X-Cache-Status $upstream_cache_status;   # 看命中情况
}

注意:动态接口别乱缓存(数据会过期);缓存要设计 key 和失效策略。


九、日志与监控

9.1 访问日志

nginx 复制代码
log_format main '$remote_addr - [$time_local] "$request" '
                '$status $body_bytes_sent "$http_referer" '
                '"$http_user_agent" "$http_x_forwarded_for" '
                'upstream:$upstream_addr $upstream_response_time';

access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log warn;

9.2 按天切割日志

bash 复制代码
# logrotate 配置 /etc/logrotate.d/nginx
/data/logs/nginx/*.log {
    daily
    rotate 30
    compress
    missingok
    notifempty
    postrotate
        /usr/sbin/nginx -s reopen
    endscript
}

坑:不切割日志,访问量大的站点一天写几个 G。

9.3 关键指标

  • $upstream_response_time:后端响应时间(Nginx 日志里看);
  • $upstream_status:后端状态码;
  • 499:客户端断开(后端处理太久);
  • 502/504:后端挂了/超时。

十、常见坑速查

现象 原因 解决
502 Bad Gateway 后端没起/端口错 检查后端、telnet 端口
504 Gateway Timeout 后端处理超时 proxy_read_timeout 调大
404(前端刷新) history 路由没配 try_files /index.html
403 Forbidden 目录权限/无 index 检查 root 权限
499 大量 客户端等不及断开 后端提速
静态资源缓存不了 没配 expires 加 expires 头
reload 后不生效 配置没写对 nginx -t 先测
后端拿不到真实 IP 没配 X-Real-IP 加 proxy_set_header

十一、Nginx 调优要点

nginx 复制代码
worker_processes auto;              # = CPU 核数
worker_connections 10240;           # 连接数

http {
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    gzip on;                        # 压缩
    gzip_types text/plain text/css application/json application/javascript;
    gzip_min_length 1k;
    client_max_body_size 50m;       # 上传大小(默认 1M 会报 413)
}

413 坑 :上传文件报 413 Request Entity Too Large------client_max_body_size 默认 1M,要调大。


本章小结

Nginx 的核心心智:server 管入口、location 管分发、upstream 管后端、proxy_pass 管转发。生产上最常用的组合是:反向代理 + 负载均衡 + 动静分离 + HTTPS + 限流。

下一篇讲 Java 并发编程------大厂面试的"必考三件套"之一。

(全文完)

相关推荐
IT大白鼠1 小时前
彭大帅的AI运维助手——自然语言管理 Linux 集群与网络设备——第 2 篇 · 安全守规矩的 AI:分级安全管控是灵魂
linux·运维·人工智能
闭包不眠1 小时前
端侧AI能省多少服务器钱:把账换成字节算
运维·服务器·图像处理·人工智能·计算机视觉
风华同学1 小时前
免密SSH登录Ubuntu
linux·运维·ubuntu
꯭自꯭闭꯭1 小时前
达梦守护集群手工切换及故障切换
linux·运维·服务器·数据库
哈__1 小时前
日志散在多台服务器怎么查?用 Promtail + Loki + Grafana 搭一套集中检索平台
运维·服务器·grafana
CHENKONG_CK1 小时前
恶劣工况下 RFID 赋能喷涂产线自动化分拣与作业
运维·网络·人工智能·自动化·汽车·rfid·rfid
wdfk_prog2 小时前
Wi-Fi Direct 教程 04:Interface 协议子系统初始化——WPA/EAPOL、WPS、DPP/NAN、GAS 与 P2P callback
android·运维·服务器·ubuntu·p2p·wps·wifi-direct
云飞云共享云桌面2 小时前
有个10人的SolidWorks设计团队,服务器什么配置合适,如何落地
运维·服务器·3d·自动化·电脑·制造
逆向编程2 小时前
VMware仅主机(Host‑Only,VMnet1)物理机‑虚拟机文件共享完整实操
运维