Nginx 反向代理
反向代理(Reverse Proxy)是一种服务器架构模式,它作为代理服务器接收来自客户端的连接请求,然后将这些请求转发到内部网络上的一个或多个后端服务器,并将从后端服务器得到的结果返回给客户端 。在此过程中,代理服务器对外表现为一个独立的服务器,有效隐藏了后端服务器的真实细节。
与正向代理代表客户端与服务器通信不同,反向代理代表服务器与客户端通信。正向代理隐藏真实客户端,而反向代理隐藏真实服务器,客户端只与反向代理服务器交互,不知道后端服务器的存在。
Nginx作为一个高性能的HTTP和反向代理服务器,以其高性能、稳定性、丰富的功能集、简单的配置和低资源消耗而闻名。
1. Nginx反向代理工作原理
Nginx反向代理的工作流程可以分为以下几个关键步骤:
-
客户端请求:客户端通过HTTP或HTTPS协议向Nginx服务器发送请求。
-
请求接收与转发:Nginx接收到请求后,根据预先配置的反向代理规则,将请求转发到一个或多个指定的后端服务器。
-
资源处理与响应:后端服务器接收到来自Nginx的请求,处理该请求并生成相应的资源响应。
-
响应返回客户端:Nginx从后端服务器接收到资源响应后,将其转发回原始请求的客户端,完成整个请求-响应周期。
在这一过程中,Nginx支持对多种协议进行代理,包括HTTP、HTTPS、TCP、WebSocket、gRPC等。
2. 配置Nginx反向代理
2.1 基本配置
配置Nginx反向代理的核心是使用proxy_pass指令。以下是一个基本的反向代理配置示例:
server {
listen 80;
server_name 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;
}
}配置说明:
-
listen 80:指定Nginx监听的端口(此处为80)
-
server_name example.com:指定该配置响应的域名
-
location /:定义匹配的URL路径(此处匹配所有路径)
-
proxy_pass http://localhost:8080:核心指令,指定请求转发的目标地址
-
proxy_set_header:设置转发到后端服务器的请求头信息
2.2 关键配置参数详解
除了基本配置外,Nginx反向代理还提供了一系列重要参数用于优化和控制代理行为:
| 参数 | 说明 | 示例值 |
|---|---|---|
| proxy_connect_timeout | 与后端服务器建立连接的超时时间 | 60s |
| proxy_send_timeout | 向后端服务器发送请求的超时时间 | 60s |
| proxy_read_timeout | 从后端服务器读取响应的超时时间 | 60s |
| proxy_buffers | 代理缓冲区的数量和大小 | 84k |
| client_body_buffer_size | 客户端请求主体的缓冲区大小 | 8k |
完整配置示例:
location / {
proxy_pass http://backend-server;
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
proxy_buffers 8 4k;
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.3 路径处理规则
在配置反向代理时,location块和proxy_pass指令的路径配置对最终转发路径有重要影响。以下是不同配置情况的路径处理规则:
| location路径 | proxy_pass路径 | 实际转发路径 | 说明 |
|---|---|---|---|
| /test/ | http://backend.com/ | http://backend.com/index.html | location有尾随斜杠,proxy_pass也有斜杠时,location匹配的路径会被替换 |
| /test/ | http://backend.com | http://backend.com/test/index.html | proxy_pass无尾随斜杠时,location匹配的路径会保留 |
| /test | http://backend.com/ | http://backend.com//index.html | 可能产生双斜杠,需要特别注意 |
| /test | http://backend.com | http://backend.com/test/index.html | 路径原样传递 |
3 反向代理高级功能
3.1 负载均衡
Nginx可以通过upstream模块实现负载均衡,将请求分发到多个后端服务器:
http {
upstream backend {
server backend1.example.com:8080 weight=3;
server backend2.example.com:8080;
server backend3.example.com:8080;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}Nginx支持多种负载均衡算法:
-
轮询(默认):按顺序将请求分发到各后端服务器
-
加权轮询:根据服务器权重分配请求
-
IP哈希:根据客户端IP地址分配,保证同一客户端访问同一服务器
-
最少连接:优先将请求分发给当前连接数最少的服务器
3.2 缓存功能
Nginx可以缓存后端服务器的响应,显著提升性能
http {
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 304 12h;
proxy_cache_valid 301 302 1m;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
}
}
}3.3 SSL终止
Nginx可以处理SSL/TLS加密,减轻后端服务器负担:
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /path/to/certificate.crt;
ssl_certificate_key /path/to/private.key;
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 https;
}
}4 实际应用场景
4.1 提高访问速度
代理服务器可以缓存静态资源,减少对后端服务器的直接请求,尤其对于热门站点可以显著提升请求速度。
4.2 安全性和访问控制
反向代理充当安全屏障,隐藏后端服务器的真实IP地址和架构细节。它可以实施访问控制、身份验证和授权策略,保护后端服务器免受恶意请求和攻击。
4.3 负载分发与高可用
通过将请求分发到多个服务器,提高系统吞吐量和可靠性。结合健康检查机制,可以自动剔除故障节点,保证服务连续性。
4.4 流量控制与DDoS防护
通过配置限流指令(如limit_req和limit_conn),Nginx可以实现流量控制功能,限制来自客户端的请求速率和并发连接数,有效防御DDoS攻击。
5 配置实践与最佳实践
5.1 完整配置示例
以下是一个结合了多种最佳实践的反向代理配置示例:
# 定义上游服务器组
upstream backend {
server 192.168.1.100:8080 weight=3;
server 192.168.1.101:8080;
server 192.168.1.102:8080 backup;
}
# HTTP服务器配置
server {
listen 80;
server_name example.com;
# 访问日志配置
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# 安全头设置
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
# 反向代理配置
location / {
proxy_pass http://backend;
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# 请求头设置
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_buffers 8 16k;
proxy_buffer_size 32k;
}
# 健康检查端点(限制访问)
location /nginx_status {
stub_status;
allow 127.0.0.1;
deny all;
}
}5.2 配置检查与故障排查
- 语法检查:修改配置后,务必执行语法检查
sudo nginx -t- 重载配置:检查无误后重载Nginx
sudo systemctl reload nginx- 日志监控:遇到问题时查看错误日志
tail -f /var/log/nginx/error.log5.3 安全最佳实践
-
限制直接IP访问:配置默认server块拒绝非域名访问
-
设置适当的超时时间:防止资源被长期占用
-
使用最小权限原则:Nginx进程应以非root用户运行
-
定期更新:保持Nginx版本最新,修复安全漏洞
6 完整示例
一个完整的示例:
user nginx;
worker_processes 1; # 根据需要调整
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024; # 允许每个 worker 进程的最大连接数
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 启用 gzip 压缩
gzip on;
#禁用版本信息
server_tokens off;
# 访问日志配置
access_log /var/log/nginx/access.log;
# 设置 SSL
server {
listen 443 ssl;
server_name xxx.cn www.xxx.cn;
ssl_certificate /etc/nginx/certs/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/privkey.pem;
location / {
proxy_pass http://172.17.0.1:8001; # halo 服务的地址和端口
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;
}
}
# 设置 SSL
server {
listen 443 ssl;
server_name store.xxx.cn;
ssl_certificate /etc/nginx/certs/store.xxx.cn_chain.crt;
ssl_certificate_key /etc/nginx/certs/store.xxx.cn_key.key;
location / {
proxy_pass http://172.17.0.1:8002; # halo 服务的地址和端口
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;
}
}
# HTTP 到 HTTPS 重定向
server {
listen 80;
server_name xxx.cn www.xxx.cn store.xxx.cn;
return 301 https://$host$request_uri;
}
server {
listen 80 default_server;
listen 443 ssl default_server;
server_name _;
ssl_certificate /etc/nginx/certs/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/privkey.pem;
return 403;
}
}7 总结
Nginx反向代理是一个功能强大且灵活的工具,通过合理的配置可以实现负载均衡、缓存加速、安全防护等多种功能。掌握其基本原理和配置技巧,对于构建高性能、高可用的Web服务架构至关重要。在实际应用中,应根据具体需求选择合适的配置策略,并遵循安全最佳实践,以确保系统的稳定性和安全性。
通过本文的介绍,您应该对Nginx反向代理有了全面的了解,能够根据实际需求配置和优化自己的反向代理服务器。
相关阅读:如果你的后端服务部署在内网,需要先从外网访问,可以搭配 FRP 内网穿透工具 将内网服务暴露到公网,再通过 Nginx 反向代理进行流量管理和 SSL 加密。