Nginx 实战:静态资源、反向代理与负载均衡
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_fails 和 fail_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 负载均衡。
- 深入学习
map、split_clients和geo模块实现更精细的路由。 - 结合 Keepalived 实现 Nginx 自身的高可用。
不断实验,查阅官方文档,Nginx 的强大能力将为你的 Web 架构提供坚实底座。