介绍
Nginx 反向代理是一种将客户端请求转发到后端服务器的技术,隐藏了真实服务器的细节,同时提供负载均衡、缓存加速、SSL 终止等功能。
快速安装Nginx
若已经安装nginx可忽略此步骤
# 更新源+安装
sudo apt update -y && sudo apt install -y nginx
# 启动并设置开机自启
sudo systemctl start nginx
sudo systemctl enable nginx
# 验证安装(输出版本即成功)
nginx -v
# 防火墙开放 80/443 端口
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw reload
Nginx 配置文件结构(关键路径)
# 主配置文件
/etc/nginx/nginx.conf
# 虚拟主机配置目录(推荐在此创建配置)
/etc/nginx/sites-available/
# 启用的虚拟主机(软链接指向 sites-available 中的配置)
/etc/nginx/sites-enabled/
# 日志目录
/var/log/nginx/
基础反向代理实战
需求:http://proxy.example.com 转发至后端服务 http://192.168.1.100:8080
创建配置文件
sudo vim /etc/nginx/sites-available/proxy-single.conf
写入配置
server {
listen 80;
server_name proxy.example.com; # 替换为你的域名/服务器IP
# 日志配置
access_log /var/log/nginx/proxy-single-access.log main;
error_log /var/log/nginx/proxy-single-error.log warn;
location / {
proxy_pass http://192.168.1.100:8080; # 后端服务地址
# 传递客户端真实IP和请求信息(后端必须配置)
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 30s; # 连接后端超时
proxy_send_timeout 30s; # 发送请求超时
proxy_read_timeout 60s; # 读取响应超时
# 缓冲区配置(处理大响应)
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 4 16k;
proxy_busy_buffers_size 32k;
}
}
启用配置并验证
# 创建软链接启用配置
sudo ln -s /etc/nginx/sites-available/proxy-single.conf /etc/nginx/sites-enabled/
# 验证配置语法
sudo nginx -t
# 重载 Nginx(不中断服务)
sudo systemctl reload nginx
# 测试代理效果(返回后端服务响应即成功)
curl http://proxy.example.com
负载均衡实战
需求:将请求分发至 3 台后端服务器,支持权重分配、故障自动切换
创建配置文件
sudo vim /etc/nginx/sites-available/proxy-lb.conf
写入配置
# 定义后端服务器集群(名称自定义)
upstream backend_cluster {
server 192.168.1.100:8080 weight=3; # 权重3,分发概率最高
server 192.168.1.101:8080 weight=2; # 权重2
server 192.168.1.102:8080 max_fails=3 fail_timeout=30s; # 3次失败标记不可用,30秒后重试
server 192.168.1.103:8080 backup; # 备用服务器(主服务全挂时启用)
# 负载均衡算法(默认轮询,可选以下)
# ip_hash; # 基于客户端IP哈希,保持会话一致性
# least_conn; # 最少连接数优先(适合后端性能不均)
}
server {
listen 80;
server_name proxy.example.com;
access_log /var/log/nginx/proxy-lb-access.log main;
error_log /var/log/nginx/proxy-lb-error.log warn;
location / {
proxy_pass http://backend_cluster; # 转发至集群
# 复用基础代理的请求头和超时配置
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_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
}
}
启用配置并验证负载效果
sudo ln -s /etc/nginx/sites-available/proxy-lb.conf /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
# 连续发送10个请求,观察后端分发情况
for i in {1..10}; do curl -I http://proxy.example.com | grep "Server" || echo "请求失败"; done
HTTPS反向代理
需求:Nginx 处理 HTTPS 加密,后端服务走 HTTP(减轻后端 CPU 负载)
申请免费 SSL 证书(Let's Encrypt)
# 安装 Certbot
sudo apt install -y certbot python3-certbot-nginx
# 申请证书(自动验证域名并配置)
sudo certbot --nginx -d proxy.example.com # 替换为你的域名
优化 SSL 配置(替换自动生成的配置)
sudo vim /etc/nginx/sites-available/proxy-ssl.conf
写入优化配置:
# HTTP 强制跳转 HTTPS
server {
listen 80;
server_name proxy.example.com;
return 301 https://$host$request_uri;
}
# HTTPS 核心配置
server {
listen 443 ssl http2; # 启用 HTTP/2,提升并发
server_name proxy.example.com;
# SSL 证书路径(Certbot 自动生成,无需修改)
ssl_certificate /etc/letsencrypt/live/proxy.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/proxy.example.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/proxy.example.com/chain.pem;
# SSL 安全+性能优化
ssl_protocols TLSv1.2 TLSv1.3; # 禁用不安全协议(TLSv1.0/TLSv1.1)
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m; # 会话缓存,提升重连速度
ssl_session_timeout 1d;
ssl_stapling on; # OCSP 装订,减少 SSL 握手时间
ssl_stapling_verify on;
resolver 8.8.8.8 1.1.1.1 valid=300s; # DNS 解析器
# 反向代理配置(可对接单后端或负载均衡集群)
location / {
proxy_pass http://backend_cluster; # 替换为你的后端/集群地址
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;
}
}
启用配置并验证
sudo ln -s /etc/nginx/sites-available/proxy-ssl.conf /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
# 测试 HTTPS 访问
curl -v https://proxy.example.com
# 在线验证 SSL 安全性(浏览器打开)
# https://www.ssllabs.com/ssltest/analyze.html?d=proxy.example.com
反向代理缓存
需求:缓存图片、CSS、JS 等静态资源,减少后端请求压力
配置全局缓存(修改主配置)
sudo vim /etc/nginx/nginx.conf
在 http 块中添加:
http {
# 其他默认配置...
# 反向代理缓存全局配置
proxy_cache_path /var/cache/nginx/proxy_cache
levels=1:2 # 缓存目录层级(1级+2级子目录)
keys_zone=proxy_cache_zone:10m # 共享内存区(名称+大小)
max_size=20g # 最大缓存磁盘空间(超出LRU淘汰)
inactive=7d # 7天未访问自动清理
use_temp_path=off; # 禁用临时目录,避免I/O竞争
proxy_cache_key "$scheme$request_method$host$request_uri$args"; # 缓存唯一标识
}
配置虚拟主机缓存规则
sudo vim /etc/nginx/sites-available/proxy-cache.conf
写入配置:
server {
listen 443 ssl http2;
server_name proxy.example.com;
# SSL 配置(复用场景3的SSL部分)
ssl_certificate /etc/letsencrypt/live/proxy.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/proxy.example.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/proxy.example.com/chain.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_prefer_server_ciphers on;
# 静态资源缓存(匹配后缀)
location ~* \.(jpg|jpeg|png|gif|css|js|pdf|ico|svg|woff2)$ {
proxy_pass http://backend_cluster;
proxy_cache proxy_cache_zone; # 启用缓存
proxy_cache_valid 200 304 7d; # 200/304状态码缓存7天
proxy_cache_valid any 1m; # 其他状态码缓存1分钟
proxy_cache_use_stale error timeout; # 后端故障时使用过期缓存
add_header X-Proxy-Cache $upstream_cache_status; # 响应头显示缓存状态(HIT/MISS)
expires 30d; # 客户端本地缓存30天
}
# 动态请求(如API)不缓存
location / {
proxy_pass http://backend_cluster;
proxy_cache off; # 禁用缓存
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
创建缓存目录并启用配置
# 创建缓存目录并授权
sudo mkdir -p /var/cache/nginx/proxy_cache
sudo chown -R nginx:nginx /var/cache/nginx/proxy_cache
# 启用配置
sudo ln -s /etc/nginx/sites-available/proxy-cache.conf /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
# 验证缓存:首次 MISS,二次 HIT
curl -I https://proxy.example.com/test.jpg
反向代理路径转发
需求:/api 转发至 API 服务,/web 转发至 Web 服务,/admin 转发至管理后台
sudo vim /etc/nginx/sites-available/proxy-path.conf
写入配置:
# 定义不同后端集群
upstream api_server {
server 192.168.1.104:8081; # API服务
}
upstream web_server {
server 192.168.1.105:8082; # Web服务
}
upstream admin_server {
server 192.168.1.106:8083; # 管理后台
}
server {
listen 443 ssl http2;
server_name proxy.example.com;
# SSL配置(复用场景3)
ssl_certificate /etc/letsencrypt/live/proxy.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/proxy.example.com/privkey.pem;
# /api 路径转发
location /api/ {
proxy_pass http://api_server/; # 末尾/保持路径一致性(如/api/user → /user)
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# /web 路径转发
location /web/ {
proxy_pass http://web_server/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# /admin 路径转发
location /admin/ {
proxy_pass http://admin_server/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
启用配置:
sudo ln -s /etc/nginx/sites-available/proxy-path.conf /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
# 测试不同路径
curl https://proxy.example.com/api/health
curl https://proxy.example.com/web/index
运维核心命令
# 验证配置语法
sudo nginx -t
# 重载配置(不中断服务)
sudo systemctl reload nginx
# 重启 Nginx
sudo systemctl restart nginx
# 查看实时访问日志
sudo tail -f /var/log/nginx/proxy-access.log
# 查看错误日志
sudo tail -f /var/log/nginx/proxy-error.log
# 清理缓存
sudo rm -rf /var/cache/nginx/proxy_cache/* && sudo systemctl reload nginx
# 续签 SSL 证书(Let's Encrypt 有效期90天)
sudo certbot renew
# 查看证书状态
sudo certbot certificates
# 禁用某个虚拟主机配置
sudo unlink /etc/nginx/sites-enabled/xxx.conf && sudo systemctl reload nginx
Ubuntu22.04 Nginx反向代理实战