Nginx 实战:静态资源、反向代理与负载均衡

FreeGuideOnline 最新 2026-06-12

Nginx 高性能 Web 服务器与反向代理

引言:为什么你需要了解 Nginx?

Nginx (Engine-X) 是当下最流行的 Web 服务器之一,它以高并发、低内存消耗、反向代理与负载均衡等能力闻名。无论是托管静态网站、加速动态应用,还是构建微服务网关,Nginx 都是不可或缺的基础设施组件。本教程从实战出发,用最清晰的示例带你掌握静态资源服务、反向代理和负载均衡三大核心场景。

环境准备

  • 操作系统:Linux(Ubuntu/CentOS)或 macOS,本教程采用 Ubuntu 22.04 示范。

  • 安装 Nginx

    sudo apt update && sudo apt install nginx -y
    
  • 验证安装

    nginx -v
    sudo systemctl status nginx
    

    访问 http://你的服务器IP 应出现 Nginx 欢迎页。

  • 目录结构

    • 配置文件主入口:/etc/nginx/nginx.conf
    • 站点专用配置:/etc/nginx/sites-available//etc/nginx/sites-enabled/
    • 默认 Web 根目录:/var/www/html

一、Nginx 基础:配置文件解读

一个典型的 Nginx 配置由 指令 构成。最外层多使用 http 块,内嵌 server 块(对应一个虚拟主机),再内嵌 location 块(处理特定 URI 请求)。

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

        location / {
            root /var/www/html;
            index index.html;
        }
    }
}
  • listen:监听的端口(IP 可选)。
  • server_name:匹配的域名或多域名。
  • location:根据 URI 路径匹配请求,可以包含修饰符 =~^~ 等。

重载配置使修改生效:sudo nginx -t && sudo systemctl reload nginx

二、静态资源服务器实战

Nginx 最基础的用法就是作为静态文件服务器,直接向客户端返回 HTML、CSS、JS、图片等文件,高效且无需后端语言参与。

2.1 搭建一个静态资源站点

创建项目目录并放入静态文件:

sudo mkdir -p /var/www/mystatic
sudo chown -R $USER:$USER /var/www/mystatic
echo "<h1>Hello from Static Nginx</h1>" > /var/www/mystatic/index.html

新建站点配置 /etc/nginx/sites-available/mystatic

server {
    listen 80;
    server_name static.example.com;   # 请替换为你的域名或IP

    root /var/www/mystatic;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

启用站点并重载:

sudo ln -s /etc/nginx/sites-available/mystatic /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

现在访问配置的域名或 IP,即可看到 Hello from Static Nginx

2.2 处理静态资源的高级优化

启用 Gzip 压缩

http 块或 server 块中添加:

gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
gzip_min_length 1000;

设置缓存头

对长期不变的静态资源(如图片、字体)设置强缓存:

location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2)$ {
    expires 1y;
    add_header Cache-Control "public, immutable";
}

限制访问带宽或并发

location /downloads/ {
    limit_rate 100k;              # 每连接限速 100KB/s
    limit_rate_after 5m;          # 下载前 5MB 不限速
    limit_conn addr 5;            # 每个 IP 最多 5 个连接
}

三、反向代理实战

反向代理是 Nginx 的强项,它位于客户端和真实后端服务器之间,接收客户端请求并转发给后端,再将响应返回客户端。这样做可以隐藏后端服务、集中处理 SSL、实现缓存和负载均衡

3.1 基础反向代理:将请求转发到本地应用

假设本地运行着一个 Node.js 应用监听 3000 端口。我们想把 app.example.com 的所有请求代理过去。

配置 /etc/nginx/sites-available/app-proxy

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

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

关键指令解释:

  • proxy_pass:后端服务地址,可以是域名、IP 或 Unix socket。
  • proxy_set_header:向后端传递必要的客户端头信息,否则后端拿不到真实客户端 IP 和主机名。

3.2 带路径重写的反向代理

有时候需要把特定路径的请求代理到另一个服务,并可能剥离前缀。例如 /api/ 的请求转发到内部 API 服务,同时去掉 /api/ 前缀。

location /api/ {
    rewrite ^/api/(.*) /$1 break;
    proxy_pass http://api_backend;
    # 添加标准代理头...
}

或者利用 proxy_pass 的 URI 拼接特性:

location /api/ {
    proxy_pass http://api_backend/;   # 结尾加 `/` 会将 /api/ 替换为 /
}

3.3 WebSocket 反向代理

Nginx 自 1.3.13 起支持 WebSocket 代理,只需添加升级头:

location /wsapp/ {
    proxy_pass http://wsbackend;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
}

3.4 反向代理优化配置

  • 增加缓冲:防止慢客户端占用后端资源。
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 32 4k;
  • 超时设置
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;

四、负载均衡实战

将流量分摊到多个后端服务器,是保障高可用和横向扩展的关键。Nginx 的 upstream 模块让你轻松定义一组后端节点。

4.1 定义 upstream 组

upstream backend_servers {
    server 192.168.1.10:3000 weight=3;
    server 192.168.1.11:3000;
    server 192.168.1.12:3000 backup;
    keepalive 32;   # 对后端保持长连接数
}

默认使用**轮询(Round Robin)**算法。可配置参数:

  • weight:权重,默认为1,数值越高分配越多请求。
  • backup:备用服务器,当所有主服务器都不可用时才启用。
  • down:标记服务器永久不可用,用于临时下线。

然后在 server 块中反向代理至该组:

location / {
    proxy_pass http://backend_servers;
    proxy_set_header ... ;
}

4.2 多种负载均衡算法

Nginx 提供多种分配策略,通过指定前缀来启用。

最少连接(Least Connections):倾向于将请求发给当前活动连接数最少的后端。

upstream backend_servers {
    least_conn;
    server 192.168.1.10:3000;
    server 192.168.1.11:3000;
}

IP 哈希(IP Hash):同一客户端 IP 的请求始终发送到同一后端,用于解决 session 保持问题(无外部存储时)。

upstream backend_servers {
    ip_hash;
    server 192.168.1.10:3000;
    server 192.168.1.11:3000;
}

通用哈希(Hash):可自定义键,如结合 cookie。

upstream backend_servers {
    hash $request_uri consistent;   # consistent 代表一致性哈希,减少节点变动影响
    server 192.168.1.10:3000;
    server 192.168.1.11:3000;
}

随机(Random):任意选择后端,适合集群规模较大且负载均衡器本身成为瓶颈的场景。

upstream backend_servers {
    random;
    server 192.168.1.10:3000;
    server 192.168.1.11:3000;
}

4.3 健康检查

Nginx 开源版使用被动健康检测。通过在 upstream 中定义 max_failsfail_timeout 来判断后端是否可用。

upstream backend_servers {
    server 192.168.1.10:3000 max_fails=3 fail_timeout=30s;
    server 192.168.1.11:3000 max_fails=3 fail_timeout=30s;
}

含义:30 秒内若出现 3 次失败,则将该节点标记为不可用,30 秒后再尝试连接。
若需要主动健康检查(定期探测),则需 Nginx Plus 商业版或开源扩展模块。

4.4 负载均衡与反向代理结合实例

一个完整的配置,同时包含静态文件服务、API 反向代理和负载均衡:

http {
    upstream api_cluster {
        least_conn;
        server 10.0.0.1:8080 weight=5 max_fails=3 fail_timeout=15s;
        server 10.0.0.2:8080 weight=3 max_fails=3 fail_timeout=15s;
        server 10.0.0.3:8080 backup;
    }

    server {
        listen 80;
        server_name myapp.com;

        # 前端静态文件
        root /var/www/myapp/dist;

        location / {
            try_files $uri $uri/ /index.html;
        }

        # 代理 API 请求
        location /api/ {
            proxy_pass http://api_cluster/;
            proxy_http_version 1.1;
            proxy_set_header Connection "";
            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;
        }

        # 静态资源缓存
        location ~* \.(?:css|js|jpg|jpeg|gif|png|ico|webp|svg)$ {
            expires 30d;
            add_header Cache-Control "public, immutable";
        }
    }
}

五、性能调优与安全实践

5.1 Worker 进程与连接数

编辑 /etc/nginx/nginx.conf

worker_processes auto;          # 自动设为 CPU 核心数
worker_connections 1024;        # 每个 worker 最大连接数
multi_accept on;                # 同时接受多个新连接
use epoll;                      # Linux 下使用 epoll 事件模型

5.2 安全加固

  • 隐藏 Nginx 版本号server_tokens off;
  • 限制请求方法:只允许 GET、HEAD、POST。
    if ($request_method !~ ^(GET|HEAD|POST)$) {
        return 405;
    }
    
  • 防止点击劫持add_header X-Frame-Options "SAMEORIGIN";
  • 配置 SSL/HTTPS (生产环境必需):使用 Let's Encrypt 证书并强制 HTTPS 跳转。
  • 限制请求速率:使用 limit_req 模块防范 DDoS。
    http {
        limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
        server {
            location /login/ {
                limit_req zone=mylimit burst=20 nodelay;
                ...
            }
        }
    }
    

5.3 日志与监控

  • 自定义访问日志格式并启用:
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';
    access_log /var/log/nginx/access.log main buffer=32k flush=5s;
    
  • 错误日志分级:error_log /var/log/nginx/error.log warn;

六、常见故障排查

  • 502 Bad Gateway:后端服务未启动或无法连接。检查 proxy_pass 地址和端口,查看后端日志。
  • 504 Gateway Timeout:后端处理超时。调整 proxy_read_timeout,优化应用性能。
  • 403 Forbidden:目录权限问题或索引文件缺失。确认 Nginx 工作进程对文件有读权限。
  • 配置文件错误:每次修改后执行 nginx -t 测试语法,再重载。

七、结语与下一步

通过本教程,你已掌握了使用 Nginx 高效托管静态资源、搭建反向代理和配置负载均衡的生产级技能。建议下一步:

  • 尝试用 Docker 部署多个后端实例,搭配 Nginx 负载均衡。
  • 深入学习 mapsplit_clientsgeo 模块实现更精细的路由。
  • 结合 Keepalived 实现 Nginx 自身的高可用。

不断实验,查阅官方文档,Nginx 的强大能力将为你的 Web 架构提供坚实底座。