搭建反向代理服务
使用 Nginx 搭建一个功能完整、安全、高性能的反向代理服务器
反向代理概述
反向代理(Reverse Proxy)是代理服务器的一种,它接收客户端的请求,然后将请求转发给后端服务器,并将后端服务器的响应返回给客户端。客户端不知道实际的后端服务器
反向代理的优势
- 负载均衡:将请求分发到多个后端服务器
- SSL 终止:在 Nginx 层处理 HTTPS,减轻后端服务器压力
- 缓存:缓存后端响应,提高性能
- 安全:隐藏后端服务器信息,提供额外的安全层
- 高可用:后端服务器故障时可以自动切换
基本反向代理配置
最简单的反向代理
nginx
server {
listen 80;
server_name proxy.example.com;
location / {
proxy_pass http://backend_server;
}
}完整的反向代理配置
nginx
server {
listen 80;
server_name proxy.example.com;
# 访问日志
access_log /var/log/nginx/proxy.access.log;
error_log /var/log/nginx/proxy.error.log;
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_set_header X-Forwarded-Proto $scheme;
# 超时设置
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# 缓冲设置
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
proxy_busy_buffers_size 8k;
}
}负载均衡配置
定义上游服务器组
nginx
# 在 http 块中定义
upstream backend_servers {
# 轮询(默认)
server 127.0.0.1:8080;
server 127.0.0.1:8081;
server 127.0.0.1:8082;
# 或者使用权重
# server 127.0.0.1:8080 weight=3;
# server 127.0.0.1:8081 weight=2;
# server 127.0.0.1:8082 weight=1;
# 或者使用 IP 哈希
# ip_hash;
# 或者使用最少连接
# least_conn;
# 健康检查
# server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
}
server {
listen 80;
server_name proxy.example.com;
location / {
proxy_pass http://backend_servers;
# 其他代理设置...
}
}负载均衡算法
- 轮询(Round Robin):默认方式,按顺序分配请求
- 权重(Weight):根据权重分配请求
- IP 哈希(IP Hash):根据客户端 IP 分配,保证同一客户端访问同一服务器
- 最少连接(Least Connections):分配给连接数最少的服务器
创建反向代理服务器配置
创建配置文件
创建配置文件 /etc/nginx/sites-available/reverse-proxy.conf:
nginx
# 反向代理服务器配置
upstream backend_servers {
# 负载均衡配置
server 127.0.0.1:8080 weight=3 max_fails=3 fail_timeout=30s;
server 127.0.0.1:8081 weight=2 max_fails=3 fail_timeout=30s;
server 127.0.0.1:8082 weight=1 max_fails=3 fail_timeout=30s backup;
# 保持连接
keepalive 32;
}
server {
listen 80;
listen [::]:80;
server_name proxy.example.com www.proxy.example.com;
# 访问日志
access_log /var/log/nginx/reverse-proxy.access.log main;
error_log /var/log/nginx/reverse-proxy.error.log warn;
# 客户端限制
client_max_body_size 100M;
client_body_buffer_size 128k;
# 主位置块
location / {
# 代理到后端服务器
proxy_pass http://backend_servers;
# 请求头设置
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-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
# 超时设置
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# 缓冲设置
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
proxy_busy_buffers_size 8k;
proxy_temp_file_write_size 8k;
# 重试设置
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_next_upstream_tries 3;
proxy_next_upstream_timeout 10s;
# 禁用代理缓冲(用于流式响应)
# proxy_buffering off;
# 保持连接
proxy_http_version 1.1;
proxy_set_header Connection "";
}
# 健康检查端点
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
# 代理 WebSocket 连接
location /ws {
proxy_pass http://backend_servers;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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;
# WebSocket 超时设置
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
}
# 静态文件直接服务(不代理)
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ {
root /var/www/static;
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
}高级配置选项
1. 缓存配置
nginx
# 在 http 块中定义缓存路径
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=backend_cache:10m max_size=1g
inactive=60m use_temp_path=off;
server {
location / {
proxy_pass http://backend_servers;
# 启用缓存
proxy_cache backend_cache;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
proxy_cache_valid any 5m;
# 缓存键
proxy_cache_key "$scheme$request_method$host$request_uri";
# 缓存控制
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_background_update on;
proxy_cache_lock on;
# 添加缓存状态头
add_header X-Cache-Status $upstream_cache_status;
}
}2. SSL 终止配置
nginx
server {
listen 443 ssl http2;
server_name proxy.example.com;
# SSL 证书配置
ssl_certificate /etc/nginx/ssl/proxy.example.com.crt;
ssl_certificate_key /etc/nginx/ssl/proxy.example.com.key;
# SSL 优化配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
location / {
proxy_pass http://backend_servers;
# 通知后端使用 HTTPS
proxy_set_header X-Forwarded-Proto https;
}
}
# HTTP 重定向到 HTTPS
server {
listen 80;
server_name proxy.example.com;
return 301 https://$server_name$request_uri;
}3. 限流配置
nginx
# 在 http 块中定义限流区域
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
server {
location / {
# 请求限流
limit_req zone=api_limit burst=20 nodelay;
# 连接限流
limit_conn conn_limit 10;
proxy_pass http://backend_servers;
}
}4. 安全头配置
nginx
server {
location / {
proxy_pass http://backend_servers;
# 安全头
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
}
}实际部署步骤
1. 创建配置文件
bash
# 创建配置文件目录(如果不存在)
mkdir -p /etc/nginx/sites-available
mkdir -p /etc/nginx/sites-enabled
# 创建反向代理配置文件
cat > /etc/nginx/sites-available/reverse-proxy.conf << 'EOF'
# 反向代理配置内容(见上文完整配置)
EOF2. 创建日志目录
bash
mkdir -p /var/log/nginx3. 启用站点
bash
# 创建符号链接启用站点
ln -sf /etc/nginx/sites-available/reverse-proxy.conf \
/etc/nginx/sites-enabled/reverse-proxy.conf
# 验证符号链接
ls -la /etc/nginx/sites-enabled/4. 测试配置
bash
# 测试配置文件语法
/usr/local/nginx/sbin/nginx -t
# 如果测试通过,重新加载配置
systemctl reload nginx
# 或
/usr/local/nginx/sbin/nginx -s reload5. 验证部署
bash
# 检查服务状态
systemctl status nginx
# 测试健康检查(使用正确的 Host 头)
curl -H "Host: proxy.example.com" http://localhost/health
# 测试代理(需要后端服务运行)
curl -H "Host: proxy.example.com" http://localhost/
# 检查配置是否加载
/usr/local/nginx/sbin/nginx -T | grep -A 10 "reverse-proxy.conf"实际部署记录
服务器信息:
- IP: 14.103.203.158
- 操作系统: CentOS Linux 7 (Core)
- Nginx 版本: 1.28.0
执行步骤:
- ✅ 创建反向代理配置文件
/etc/nginx/sites-available/reverse-proxy.conf - ✅ 创建日志目录
/var/log/nginx - ✅ 启用站点(创建符号链接)
- ✅ 测试配置文件语法
- ✅ 重新加载 Nginx 配置
- ✅ 验证服务状态和健康检查端点
配置要点:
- Upstream 配置:
backend_servers指向127.0.0.1:8080 - 负载均衡:使用权重配置(weight=3)
- 健康检查:配置了
max_fails=3和fail_timeout=30s - WebSocket 支持:配置了
/ws路径的 WebSocket 代理 - 静态文件:配置了静态文件直接服务,不经过代理
验证结果:
- ✅ 健康检查端点
/health正常响应 - ✅ 配置文件语法正确
- ✅ 服务正常运行
- ✅ 配置已成功加载
注意事项:
- 由于
server_name配置为proxy.example.com,访问时需要使用 Host 头或修改本地 hosts 文件 - 后端服务需要运行在配置的端口(默认 8080)才能正常代理
- 如果后端服务未运行,代理请求会返回 502 Bad Gateway
常见配置场景
场景 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;
}
}场景 2:代理到多个后端服务(负载均衡)
nginx
upstream app_servers {
server 192.168.1.10:8080 weight=3;
server 192.168.1.11:8080 weight=2;
server 192.168.1.12:8080 weight=1;
}
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://app_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}场景 3:路径路由
nginx
server {
listen 80;
server_name example.com;
# API 请求代理到后端 API 服务器
location /api/ {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
}
# 静态文件直接服务
location /static/ {
root /var/www;
expires 1y;
}
# 其他请求代理到 Web 服务器
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
}
}场景 4:WebSocket 代理
nginx
upstream websocket_backend {
server 127.0.0.1:8080;
}
server {
listen 80;
server_name ws.example.com;
location / {
proxy_pass http://websocket_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 86400s;
}
}监控和维护
查看代理状态
bash
# 查看访问日志
tail -f /var/log/nginx/reverse-proxy.access.log
# 查看错误日志
tail -f /var/log/nginx/reverse-proxy.error.log
# 查看后端服务器状态
curl http://localhost/health性能调优
nginx
# 在 http 块中优化
http {
# 增加缓冲大小
proxy_buffer_size 8k;
proxy_buffers 16 8k;
proxy_busy_buffers_size 16k;
# 启用 keepalive
upstream backend_servers {
keepalive 32;
}
}测试后端服务
创建简单的测试后端服务
为了测试反向代理功能,可以创建一个简单的测试后端服务:
方法 1:使用 Python 创建简单 HTTP 服务器
bash
# 创建测试目录和文件
mkdir -p /tmp/backend_test
echo "<h1>Backend Server Response</h1><p>This is a test backend server running on port 8080</p>" > /tmp/backend_test/index.html
# 启动 Python HTTP 服务器(在后台运行)
cd /tmp/backend_test
nohup python3 -m http.server 8080 > /tmp/backend_server.log 2>&1 &
# 检查服务是否运行
curl http://127.0.0.1:8080方法 2:使用 Nginx 作为测试后端
bash
# 创建一个简单的 Nginx 配置作为后端
cat > /etc/nginx/sites-available/backend-test.conf << 'EOF'
server {
listen 8080;
server_name localhost;
root /tmp/backend_test;
index index.html;
}
EOF
ln -sf /etc/nginx/sites-available/backend-test.conf /etc/nginx/sites-enabled/
systemctl reload nginx测试反向代理
bash
# 1. 测试健康检查
curl -H "Host: proxy.example.com" http://localhost/health
# 2. 测试代理到后端(需要后端服务运行)
curl -H "Host: proxy.example.com" http://localhost/
# 3. 查看代理日志
tail -f /var/log/nginx/reverse-proxy.access.log
# 4. 测试 WebSocket 代理(如果有 WebSocket 服务)
curl -H "Host: proxy.example.com" -H "Upgrade: websocket" http://localhost/ws故障排查
常见问题
-
502 Bad Gateway
- 检查后端服务是否运行:
curl http://127.0.0.1:8080 - 检查后端服务地址和端口是否正确
- 检查防火墙设置:
firewall-cmd --list-ports - 查看错误日志:
tail -50 /var/log/nginx/reverse-proxy.error.log
- 检查后端服务是否运行:
-
504 Gateway Timeout
- 增加
proxy_read_timeout值 - 检查后端服务响应时间
- 检查网络连接:
ping backend_server_ip
- 增加
-
连接被拒绝
- 检查后端服务是否监听正确端口:
netstat -tlnp | grep 8080 - 检查 SELinux 设置(如果启用):
getenforce - 检查后端服务日志
- 检查后端服务是否监听正确端口:
-
请求被错误的路由
- 检查
server_name配置是否正确 - 使用正确的 Host 头访问:
curl -H "Host: proxy.example.com" http://localhost/ - 检查是否有其他 server 块匹配了请求
- 检查
调试命令
bash
# 测试后端服务连接
curl -v http://127.0.0.1:8080
# 检查端口监听
netstat -tlnp | grep 8080
# 或
ss -tlnp | grep 8080
# 查看 Nginx 错误日志
tail -50 /var/log/nginx/reverse-proxy.error.log
# 查看访问日志
tail -50 /var/log/nginx/reverse-proxy.access.log
# 测试配置
/usr/local/nginx/sbin/nginx -t
# 查看完整配置
/usr/local/nginx/sbin/nginx -T | grep -A 20 "upstream backend_servers"
# 检查进程
ps aux | grep nginx
# 检查服务状态
systemctl status nginx性能调优建议
nginx
# 1. 增加缓冲区大小(处理大响应)
proxy_buffer_size 8k;
proxy_buffers 16 8k;
proxy_busy_buffers_size 16k;
# 2. 启用 keepalive 连接
upstream backend_servers {
keepalive 32;
# ...
}
# 3. 调整超时时间(根据实际需求)
proxy_connect_timeout 30s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# 4. 启用缓存(对于静态内容)
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=backend_cache:10m;
proxy_cache backend_cache;