Nginx 反向代理与负载均衡
Nginx 是高性能的 HTTP 和反向代理服务器,也是邮件代理服务器。
一、Nginx 核心功能
1. 正向代理 vs 反向代理
正向代理(代理客户端):
客户端 → 代理服务器 → 目标服务器
(VPN、科学上网)
反向代理(代理服务端):
客户端 → Nginx → 后端服务器
(负载均衡、隐藏后端)2. 核心特性
| 特性 | 说明 |
|---|---|
| 反向代理 | 隐藏后端服务器 |
| 负载均衡 | 分发请求到多台服务器 |
| 静态资源 | 高性能静态文件服务 |
| 虚拟主机 | 一个 Nginx 托管多个域名 |
| HTTPS | SSL/TLS 终止 |
| 缓存 | 代理缓存加速 |
二、基本配置
1. 配置文件结构
# /etc/nginx/nginx.conf
# 全局配置
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
# 事件配置
events {
worker_connections 1024;
}
# HTTP 配置
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent"';
access_log /var/log/nginx/access.log main;
# 包含其他配置
include /etc/nginx/conf.d/*.conf;
}2. Server 配置
server {
listen 80;
server_name example.com www.example.com;
# 根目录
root /var/www/html;
index index.html index.htm;
# 位置匹配
location / {
try_files $uri $uri/ =404;
}
# 静态资源
location /static/ {
alias /var/www/static/;
expires 30d;
}
# 错误页面
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
}三、反向代理配置
1. 基本代理
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://localhost: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_set_header X-Forwarded-Proto $scheme;
}
}2. 代理常用参数
location / {
proxy_pass http://backend;
# 请求头设置
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_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# 缓冲设置
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
# WebSocket 支持
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}四、负载均衡
1. Upstream 配置
upstream backend {
server 192.168.1.101:8080 weight=3;
server 192.168.1.102:8080 weight=2;
server 192.168.1.103:8080 weight=1;
server 192.168.1.104:8080 backup; # 备用服务器
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}2. 负载均衡策略
| 策略 | 说明 | 配置 |
|---|---|---|
| 轮询(默认) | 按顺序分发 | 无需配置 |
| 权重 | 按权重比例分发 | weight=n |
| IP 哈希 | 同一 IP 固定服务器 | ip_hash |
| 最少连接 | 分发到连接最少的服务器 | least_conn |
| URL 哈希 | 同一 URL 固定服务器 | hash $request_uri |
权重轮询:
upstream backend {
server 192.168.1.101:8080 weight=3; # 3/5 请求
server 192.168.1.102:8080 weight=2; # 2/5 请求
}IP 哈希:
upstream backend {
ip_hash;
server 192.168.1.101:8080;
server 192.168.1.102:8080;
}
# 适用:Session 保持最少连接:
upstream backend {
least_conn;
server 192.168.1.101:8080;
server 192.168.1.102:8080;
}
# 适用:请求处理时间差异大3. 健康检查
upstream backend {
server 192.168.1.101:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.102:8080 max_fails=3 fail_timeout=30s;
}
# max_fails: 最大失败次数
# fail_timeout: 失败后暂停时间主动健康检查(需第三方模块):
upstream backend {
server 192.168.1.101:8080;
check interval=3000 rise=2 fall=3 timeout=1000;
}
# interval: 检查间隔
# rise: 连续成功次数认为恢复
# fall: 连续失败次数认为宕机五、Location 匹配规则
1. 匹配语法
location [=|~|~*|^~] /uri/ {
# ...
}| 修饰符 | 说明 | 示例 |
|---|---|---|
= | 精确匹配 | location = /api |
~ | 正则匹配(区分大小写) | location ~ \.php$ |
~* | 正则匹配(不区分大小写) | `location ~* .(gif |
^~ | 前缀匹配,优先级高于正则 | location ^~ /static/ |
| 无 | 普通前缀匹配 | location /api/ |
2. 匹配优先级
1. = 精确匹配(最高)
2. ^~ 前缀匹配
3. ~ / ~* 正则匹配(按出现顺序)
4. 无修饰符前缀匹配(最长匹配)3. 匹配示例
# 精确匹配 /api
location = /api {
proxy_pass http://api-server;
}
# 前缀匹配,优先级高于正则
location ^~ /static/ {
alias /var/www/static/;
}
# 正则匹配图片
location ~* \.(gif|jpg|jpeg|png)$ {
expires 30d;
}
# 前缀匹配
location /api/ {
proxy_pass http://api-server/;
}六、HTTPS 配置
1. SSL 证书配置
server {
listen 443 ssl;
server_name example.com;
# SSL 证书
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
# SSL 参数
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
location / {
proxy_pass http://localhost:8080;
}
}
# HTTP 重定向到 HTTPS
server {
listen 80;
server_name example.com;
return 301 https://$server_name$request_uri;
}2. HTTP/2 配置
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
# ...
}七、缓存配置
1. 静态资源缓存
location ~* \.(css|js|jpg|jpeg|png|gif|ico|woff|woff2)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}2. 代理缓存
# 缓存配置
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=api_cache:10m
max_size=1g inactive=60m use_temp_path=off;
server {
location /api/ {
proxy_pass http://backend;
# 启用缓存
proxy_cache api_cache;
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_cache_valid 200 10m;
proxy_cache_valid 404 1m;
# 添加缓存状态头
add_header X-Cache-Status $upstream_cache_status;
}
}八、限流配置
1. 请求限流
# 定义限流区域
limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;
server {
location /api/ {
# 应用限流
limit_req zone=req_limit burst=20 nodelay;
# 超限返回 429
limit_req_status 429;
proxy_pass http://backend;
}
}2. 连接限流
# 定义连接限制区域
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
server {
location /api/ {
# 限制每个 IP 最多 10 个连接
limit_conn conn_limit 10;
proxy_pass http://backend;
}
}九、面试高频问题
Q1: Nginx 为什么高性能?
- 事件驱动:epoll 模型,非阻塞 I/O
- 多进程模型:master-worker 架构
- 异步处理:不阻塞 worker 进程
- 内存池:减少内存碎片
Q2: worker_processes 应该设置多少?
worker_processes auto; # 自动设置为 CPU 核心数Q3: 负载均衡策略如何选择?
| 场景 | 推荐策略 |
|---|---|
| 服务器性能相近 | 轮询/权重轮询 |
| 需要 Session 保持 | IP 哈希 |
| 请求处理时间差异大 | 最少连接 |
| 缓存场景 | URL 哈希 |
Q4: upstream 5xx 错误如何处理?
upstream backend {
server 192.168.1.101:8080;
server 192.168.1.102:8080;
}
server {
location / {
proxy_pass http://backend;
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
proxy_next_upstream_tries 3; # 最大重试次数
}
}Q5: 如何实现灰度发布?
# 基于权重
upstream backend {
server 192.168.1.101:8080 weight=9; # 90% 流量
server 192.168.1.102:8080 weight=1; # 10% 流量(新版本)
}
# 基于 Cookie
map $cookie_version $backend {
default stable;
"canary" canary;
}
upstream stable {
server 192.168.1.101:8080;
}
upstream canary {
server 192.168.1.102:8080;
}
server {
location / {
proxy_pass http://$backend;
}
}十、最佳实践
1. 安全配置
# 隐藏版本号
server_tokens off;
# 禁止访问隐藏文件
location ~ /\. {
deny all;
}
# 防盗链
location ~* \.(jpg|jpeg|png|gif)$ {
valid_referers none blocked example.com *.example.com;
if ($invalid_referer) {
return 403;
}
}
# 安全头
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header X-XSS-Protection "1; mode=block";2. 性能优化
# 开启 gzip
gzip on;
gzip_types text/plain text/css application/json application/javascript;
gzip_min_length 1000;
# 开启文件缓存
open_file_cache max=1000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
# 优化连接
keepalive_timeout 65;
keepalive_requests 100;3. 日志配置
# 自定义日志格式
log_format json escape=json '{'
'"time":"$time_iso8601",'
'"remote_addr":"$remote_addr",'
'"request":"$request",'
'"status":$status,'
'"body_bytes_sent":$body_bytes_sent,'
'"request_time":$request_time,'
'"upstream_response_time":"$upstream_response_time"'
'}';
access_log /var/log/nginx/access.log json;更新时间:2026年3月16日