Nginx 通过高效地将客户端请求转发到后端服务器并返回其响应,充当高性能代理服务器,从而实现负载均衡、SSL 终止和内容缓存等功能。
简介
Nginx(Engine-X)是一款开源 Web 服务器,同时也可以作为反向代理、HTTP 缓存和负载均衡器运行。其事件驱动架构使它能够高效处理大量并发连接,适用于高流量环境。作为代理时,Nginx 位于客户端与后端服务器之间,居中转发流量并叠加额外的功能层。
为什么用 Nginx 作代理?
将 Nginx 部署为代理服务器可带来多项运维优势:
- 负载均衡: 将进入的网络流量分发到多台后端服务器,提升应用的响应速度与可靠性。
- SSL/TLS 终止: 处理来自客户端的加密连接,在转发到后端服务器之前完成解密,后端因此可以使用未加密的 HTTP 通信。这将加解密开销从应用服务器上卸载。
- 缓存: 存储高频访问的内容,降低后端服务器负载并缩短客户端的响应时间。
- 安全: 作为缓冲层,屏蔽后端服务器免受客户端直接访问和潜在攻击。它可以过滤请求并执行访问策略。
- 高可用: 配合负载均衡,Nginx 可以把流量从不健康的后端服务器上移开,保证服务持续可用。
- 流量管理: 支持 URL 重写、请求过滤和内容改写。
Nginx 代理类型
Nginx 主要有两种代理模式:反向代理和正向代理。
反向代理
反向代理代表客户端从一台或多台服务器获取资源,然后把这些资源返回给客户端,看起来就像是代理服务器本身提供的一样。客户端并不知道后端架构。
正向代理
正向代理代表客户端从各类外部服务器获取资源。它是客户端向外部服务器请求资源时的中间人。客户端需要显式配置才能使用正向代理。
| 特性 | 反向代理 | 正向代理 |
|---|---|---|
| 客户端感知 | 客户端不知道代理的存在;请求直接发往代理。 | 客户端知道代理并已配置为使用它。 |
| 用途 | 保护并优化后端服务器;负载均衡。 | 让客户端访问外部资源;安全/过滤。 |
| 位置 | 通常部署在 Web 服务器前端。 | 通常部署在客户端网络边缘。 |
| 透明性 | 对客户端而言表现为源服务器。 | 对客户端而言表现为中间人。 |
基础反向代理配置
将 Nginx 配置为反向代理,需要定义一个监听请求的 server 块,然后使用 proxy_pass 指令把请求转发到上游服务器。
前置条件
- 已安装的 Nginx 实例。
- 对 Nginx 配置文件的访问权限(通常是
/etc/nginx/nginx.conf或/etc/nginx/sites-available/下的文件)。 - 一台正在运行且 Nginx 服务器可以访问的后端服务器(例如应用服务器或另一台 Web 服务器)。
核心配置指令
proxy_pass:转发请求的基础指令,指定被代理服务器的协议、地址和可选端口。proxy_set_header:修改 Nginx 发送给被代理服务器的请求头。传递客户端 IP、host 和协议信息时必不可少。proxy_buffering:控制 Nginx 是否缓冲被代理服务器的响应。缓冲可让 Nginx 先接收完整响应再发给客户端,从而提升性能。proxy_cache:启用对被代理服务器响应的缓存。
# /etc/nginx/sites-available/my_reverse_proxy.conf
server {
listen 80;
server_name example.com www.example.com;
location / {
# 目标后端服务器
proxy_pass http://backend_app_server:8080;
# 将原始 host 和 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;
# 流式传输时关闭代理缓冲,传统 Web 场景可开启
# proxy_buffering on;
}
# 可选:由 Nginx 直接提供静态文件
location /static/ {
root /var/www/my_app;
expires 30d;
}
}
创建该文件后,通过在 sites-enabled 中建立符号链接来启用它:
sudo ln -s /etc/nginx/sites-available/my_reverse_proxy.conf /etc/nginx/sites-enabled/
然后测试 Nginx 配置并重新加载:
sudo nginx -t
sudo systemctl reload nginx
进阶反向代理配置
负载均衡
Nginx 可以使用多种负载均衡算法把请求分发到多台后端服务器。upstream 块用于定义一组服务器。
# 位于 nginx.conf 中,或由 http 块 include 的独立文件
upstream backend_servers {
# 轮询(默认)
server backend_server1.example.com:8080;
server backend_server2.example.com:8080;
server 192.168.1.100:8080; # 也可以使用 IP 地址
# 加权轮询
# server backend_server1.example.com:8080 weight=3;
# server backend_server2.example.com:8080 weight=1;
# 最少连接
# least_conn;
# IP Hash(基于客户端 IP 的会话保持)
# ip_hash;
# 健康检查(需要 Nginx Plus 或特定模块)
# server backend_server1.example.com:8080 max_fails=3 fail_timeout=30s;
}
server {
listen 80;
server_name myapp.example.com;
location / {
proxy_pass http://backend_servers; # 引用 upstream 块
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
SSL/TLS 终止
Nginx 可以终止 SSL/TLS 连接,把加解密过程从后端服务器上卸载。这需要 SSL 证书和私钥。
server {
listen 443 ssl;
server_name secure.example.com;
ssl_certificate /etc/nginx/ssl/secure.example.com.crt;
ssl_certificate_key /etc/nginx/ssl/secure.example.com.key;
# 兼顾安全与性能的推荐 SSL 设置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1h;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
location / {
proxy_pass http://backend_app_server:8080; # 后端可以使用 HTTP
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 secure.example.com;
return 301 https://$host$request_uri;
}
缓存
Nginx 可以缓存被代理服务器的响应,对静态或很少变化的内容能显著降低延迟和后端负载。
# 位于 http 块中(在任何 server 块之外)
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m inactive=60m max_size=1g;
proxy_cache_key "$scheme$request_method$host$request_uri";
server {
listen 80;
server_name cache.example.com;
location / {
proxy_pass http://backend_app_server:8080;
proxy_set_header Host $host;
proxy_cache my_cache; # 为该 location 启用缓存
proxy_cache_valid 200 302 10m; # 200/302 响应缓存 10 分钟
proxy_cache_valid 404 1m; # 404 响应缓存 1 分钟
proxy_cache_bypass $http_pragma $http_authorization; # 出现这些头时不写入缓存
proxy_no_cache $http_pragma $http_authorization; # 出现这些头时不使用缓存
add_header X-Proxy-Cache $upstream_cache_status; # 添加响应头以查看缓存状态
}
}
代理 WebSocket
代理 WebSocket 需要专门处理 Upgrade 和 Connection 头,以完成协议切换。
server {
listen 80;
server_name websocket.example.com;
location /ws/ {
proxy_pass http://backend_websocket_server:8081;
# WebSocket 专用请求头
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; # 长连接场景可按需调整
}
}
基础正向代理配置
将 Nginx 配置为正向代理,可让客户端通过 Nginx 转发其出站请求。这通常用于企业网络中的访问控制或日志记录。
配置指令
resolver:指定 Nginx 用于解析主机名的 DNS 服务器。proxy_pass:在location块中使用,但目标 URL 用变量表示。
# 位于 http 块中(在任何 server 块之外)
resolver 8.8.8.8 8.8.4.4 valid=300s; # Google 公共 DNS,可按需调整
server {
listen 3128; # 代理服务器的常用端口
listen [::]:3128;
# 仅允许授权客户端访问(例如内网)
allow 192.168.1.0/24;
deny all;
location / {
proxy_pass $scheme://$host$request_uri;
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_no_cache 1;
proxy_cache_bypass 1;
}
}
之后客户端需要在浏览器或应用中把 nginx_ip_address:3128 配置为代理。
监控与排障
要让 Nginx 作为代理稳定运行,需要具备监控和排障手段。
- 配置测试: 重新加载 Nginx 之前始终校验配置文件。
sudo nginx -t - 服务状态: 检查 Nginx 服务状态。
sudo systemctl status nginx - 访问日志: Nginx 会把处理的每个请求记录到访问日志,通常位于
/var/log/nginx/access.log。日志中包含客户端 IP、请求方法、URL、状态码和响应大小等细节。 - 错误日志: 严重错误、告警和调试信息写入错误日志,通常位于
/var/log/nginx/error.log。请监控该文件,以发现配置、后端连通性或资源限制方面的问题。 - 后端健康状况: 确保后端服务器正常运行且可从 Nginx 服务器访问。在 Nginx 机器上使用
curl或ping等工具测试连通性。 - 网络连通性: 核实客户端、Nginx 与后端服务器之间的网络链路。
- 资源占用: 监控 Nginx 服务器的 CPU、内存和磁盘 I/O,以定位瓶颈。
