一文掌握 Nginx 反向代理:从入门到生产级配置
Nginx作为高性能的HTTP服务器和反向代理服务器,在现代Web架构中扮演着至关重要的角色。反向代理是Nginx的核心功能之一,它能够将客户端请求转发到后端服务器,并将响应返回给客户端,为负载均衡、安全防护、SSL终止等提供了强大的支持。
反向代理基本概念
反向代理(Reverse Proxy)是指代理服务器端的请求,客户端并不知道实际提供服务的服务器。与正向代理不同,反向代理隐藏了后端服务器的真实IP地址,客户端直接与代理服务器通信。
反向代理的优势
| 优势 | 说明 |
|---|---|
| 负载均衡 | 分发请求到多个后端服务器 |
| 安全防护 | 隐藏后端服务器真实地址 |
| SSL终止 | 在代理层处理SSL加密解密 |
| 缓存加速 | 缓存静态资源提高响应速度 |
| 高可用性 | 提供故障转移和健康检查 |
基础反向代理配置
简单反向代理
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend_server;
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;
}
}
后端服务器组配置
pstream backend_servers {
server 192.168.1.10:8080 weight=3;
server 192.168.1.11:8080 weight=2;
server 192.168.1.12:8080 backup;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend_servers;
}
}
负载均衡策略
轮询(Round Robin)
upstream backend {
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}
加权轮询
upstream backend {
server backend1.example.com weight=3;
server backend2.example.com weight=2;
server backend3.example.com weight=1;
}
IP哈希
upstream backend {
ip_hash;
server backend1.example.com;
server backend2.example.com;
}
最少连接
upstream backend {
least_conn;
server backend1.example.com;
server backend2.example.com;
}
高级反向代理配置
健康检查配置
upstream backend {
server backend1.example.com max_fails=3 fail_timeout=30s;
server backend2.example.com max_fails=3 fail_timeout=30s;
server backend3.example.com max_fails=3 fail_timeout=30s;
}
连接和超时配置
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend;
# 连接超时
proxy_connect_timeout 30s;
# 发送超时
proxy_send_timeout 60s;
# 接收超时
proxy_read_timeout 60s;
# 缓冲区配置
proxy_buffer_size 4k;
proxy_buffers 8 4k;
proxy_busy_buffers_size 8k;
}
}
请求和响应头处理
server {
listen 80;
server_name example.com;
location /api/ {
proxy_pass http://api_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_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Original-URI $request_uri;
# 修改响应头
proxy_hide_header X-Powered-By;
add_header X-Proxy-Cache $upstream_cache_status;
add_header X-Upstream-Status $upstream_status;
}
}
SSL/TLS配置
SSL终止
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /path/to/certificate.crt;
ssl_certificate_key /path/to/private.key;
# SSL安全配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
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_set_header X-Forwarded-Proto https;
}
}
重定向HTTP到HTTPS
server {
listen 80;
server_name example.com;
return 301 https://$server_name$request_uri;
}
缓存配置
简单缓存
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=10g
inactive=60m use_temp_path=off;
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend;
# 启用缓存
proxy_cache my_cache;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
# 缓存键
proxy_cache_key $scheme$request_method$host$request_uri;
# 缓存头
add_header X-Cache-Status $upstream_cache_status;
}
}
高级缓存配置
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=static_cache:10m
max_size=50g inactive=1h use_temp_path=off;
server {
listen 80;
server_name example.com;
# 静态资源缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
proxy_pass http://static_backend;
proxy_cache static_cache;
proxy_cache_valid 200 1h;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_background_update on;
proxy_cache_lock on;
}
# API缓存
location /api/ {
proxy_pass http://api_backend;
proxy_cache my_cache;
proxy_cache_valid 200 5m;
proxy_cache_bypass $http_cache_control;
add_header X-Cache-Status $upstream_cache_status;
}
}
安全配置
防止DDoS攻击
限制请求频率
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=login:10m rate=1r/s;
server {
listen 80;
server_name example.com;
location /api/ {
limit_req zone=api burst=20 nodelay;
proxy_pass http://api_backend;
}
location /login {
limit_req zone=login burst=3 nodelay;
proxy_pass http://auth_backend;
}
}
隐藏版本信息
server {
listen 80;
server_name example.com;
# 隐藏Nginx版本
server_tokens off;
location / {
proxy_pass http://backend;
proxy_hide_header X-Powered-By;
proxy_hide_header Server;
}
}
生产级完整配置示例
主配置文件
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
use epoll;
multi_accept on;
}
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" "$http_x_forwarded_for" '
'rt=$request_time uct="$upstream_connect_time" '
'uht="$upstream_header_time" urt="$upstream_response_time"';
access_log /var/log/nginx/access.log main;
# 基本设置
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
client_max_body_size 16M;
# Gzip压缩
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_proxied any;
gzip_comp_level 6;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/json
application/javascript
application/xml+rss
application/atom+xml
image/svg+xml;
# 缓存路径
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=main_cache:100m
max_size=10g inactive=60m use_temp_path=off;
# 限制区域
limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m;
# 后端服务器组
upstream app_backend {
least_conn;
server app1.example.com:8080 weight=3 max_fails=2 fail_timeout=30s;
server app2.example.com:8080 weight=3 max_fails=2 fail_timeout=30s;
server app3.example.com:8080 weight=2 max_fails=2 fail_timeout=30s;
keepalive 32;
}
upstream api_backend {
ip_hash;
server api1.example.com:8080 max_fails=2 fail_timeout=30s;
server api2.example.com:8080 max_fails=2 fail_timeout=30s;
}
# HTTP服务器 - 重定向到HTTPS
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
# HTTPS服务器
server {
listen 443 ssl http2;
server_name example.com www.example.com;
# SSL配置
ssl_certificate /path/to/certificate.crt;
ssl_certificate_key /path/to/private.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# 安全头
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options DENY always;
add_header X-Content-Type-Options nosniff always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# 限制
limit_req zone=general burst=20 nodelay;
limit_conn conn_limit_per_ip 10;
# 静态资源
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|ttf|eot)$ {
proxy_pass http://static_backend;
proxy_cache main_cache;
proxy_cache_valid 200 1h;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
expires 1y;
add_header Cache-Control "public, immutable";
add_header X-Cache-Status $upstream_cache_status;
}
# API接口
location /api/ {
proxy_pass http://api_backend;
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;
# 缓存配置
proxy_cache main_cache;
proxy_cache_valid 200 5m;
proxy_cache_bypass $http_cache_control;
add_header X-Cache-Status $upstream_cache_status;
# 超时配置
proxy_connect_timeout 5s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
}
# 应用程序
location / {
proxy_pass http://app_backend;
proxy_http_version 1.1;
# 请求头
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_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# 超时配置
proxy_connect_timeout 5s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
# 缓冲区
proxy_buffer_size 4k;
proxy_buffers 8 4k;
proxy_busy_buffers_size 8k;
}
}
}
监控和日志
自定义日志格式
og_format detailed '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'rt=$request_time uct="$upstream_connect_time" '
'uht="$upstream_header_time" urt="$upstream_response_time" '
'upstream_addr=$upstream_addr';
错误页面配置
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
性能优化建议
- 启用Gzip压缩:减少传输数据量
- 合理配置缓冲区:提高响应速度
- 使用HTTP/2:提升传输效率
- 配置缓存策略:减少后端压力
- 启用连接复用:减少连接建立开销
- 限制请求频率:防止恶意攻击
故障排查
常见问题及解决方案
- 502 Bad Gateway:检查后端服务器状态和网络连通性
- 504 Gateway Timeout:调整proxy_read_timeout参数
- 413 Request Entity Too Large:调整client_max_body_size参数
- SSL握手失败:检查证书配置和协议版本
通过以上配置,可以构建一个高可用、高性能的Nginx反向代理系统,为现代Web应用提供稳定可靠的服务。
关于作者
🌟 我是suxiaoxiang,一位热爱技术的开发者
💡 专注于Java生态和前沿技术分享
🚀 持续输出高质量技术内容
如果这篇文章对你有帮助,请支持一下:
👍 点赞
⭐ 收藏
👀 关注
您的支持是我持续创作的动力!感谢每一位读者的关注与认可!