Nginx作为当今最流行的Web服务器和反向代理软件,承载着互联网上超过三分之一的网站流量。其事件驱动的异步非阻塞架构,使其能够在单机上处理数万并发连接。本文将从实际运维角度出发,详细讲解Nginx反向代理的高级配置,涵盖负载均衡策略、动态限流、健康检查以及性能调优等核心主题。
一、反向代理基础架构
反向代理是Nginx最核心的功能之一。客户端请求首先到达Nginx,由Nginx根据配置规则将请求转发到后端服务器,再将响应返回给客户端。这种架构带来了负载均衡、SSL终结、缓存加速、安全防护等诸多好处。
最基础的反向代理配置如下:
server {
listen 80;
server_name api.example.com;
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 $scheme;
}
location /static/ {
proxy_pass http://backend_static;
proxy_cache_valid 200 1h;
}
}
这里有几个关键的proxy_set_header指令需要注意。X-Real-IP将客户端真实IP传递给后端,X-Forwarded-For记录完整的代理链路,X-Forwarded-Proto让后端知道原始请求是HTTP还是HTTPS。
二、负载均衡策略深度解析
Nginx支持多种负载均衡算法,每种算法适用于不同的业务场景:
upstream backend {
# 轮询(默认)
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
}
upstream backend_weighted {
# 加权轮询:按服务器性能分配权重
server 192.168.1.10:8080 weight=5;
server 192.168.1.11:8080 weight=3;
server 192.168.1.12:8080 weight=2;
}
upstream backend_ip_hash {
# IP哈希:同一客户端IP固定访问同一后端(会话保持)
ip_hash;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
upstream backend_least_conn {
# 最少连接数:优先分配给当前连接数最少的后端
least_conn;
server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.12:8080 max_fails=3 fail_timeout=30s;
}
max_fails和fail_timeout参数控制健康检查:如果在fail_timeout时间内失败次数达到max_fails,Nginx会将该后端标记为不可用,在fail_timeout时间后再次尝试。slow_start参数让刚恢复的服务器逐步接收流量,避免突然涌入的请求压垮尚未完全就绪的服务。
三、动态限流配置
在高并发场景下,限流是保护后端服务的重要手段。Nginx提供了基于漏桶算法的限流模块:
# 在 http 块中定义限流区域
http {
# 按客户端IP限流:每秒10个请求
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
# 按客户端IP限流:每秒5个请求(上传接口更严格)
limit_req_zone $binary_remote_addr zone=upload_limit:10m rate=5r/s;
# 连接数限制
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
server {
listen 80;
# 全局连接数限制:每个IP最多100个并发连接
limit_conn conn_limit 100;
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
limit_req_status 429;
proxy_pass http://backend;
}
location /upload {
limit_req zone=upload_limit burst=5 nodelay;
limit_req_status 429;
proxy_pass http://backend;
}
}
}
burst参数允许突发流量的缓冲队列大小,nodelay表示队列中的请求立即处理而不延迟。如果不设置nodelay,突发请求会被排队延迟处理,这对实时性要求高的接口不合适。
四、健康检查与故障转移
Nginx开源版的被动健康检查已经能满足大部分需求,但对于关键业务,主动健康检查更为可靠:
upstream backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080 backup; # 备用服务器,主服务器全部故障时启用
server 192.168.1.12:8080 down; # 手动标记为下线
# 被动健康检查参数
server 192.168.1.13:8080 max_fails=2 fail_timeout=10s slow_start=30s;
}
# 主动健康检查(需 nginx_upstream_check_module)
upstream backend_checked {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
check interval=3000 rise=2 fall=3 timeout=2000 type=http;
check_http_send "HEAD /health HTTP/1.0\r\n\r\n";
check_http_expect_alive http_2xx http_3xx;
}
check指令的interval参数设置检查间隔,rise设置连续成功几次后标记为可用,fall设置连续失败几次后标记为不可用。这种主动探测方式能够在后端服务出现问题时更快地将其摘除。
五、性能调优关键参数
要让Nginx发挥最大性能,需要根据硬件配置和业务特点调整系统参数和Nginx配置:
# 系统层面调优(/etc/sysctl.conf)
fs.file-max = 1000000
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.ip_local_port_range = 1024 65535
# Nginx 配置调优
worker_processes auto; # 自动按CPU核心数设置
worker_rlimit_nofile 100000; # 每个worker最大文件描述符
events {
worker_connections 20000; # 每个worker最大连接数
use epoll; # Linux下使用epoll
multi_accept on; # 一次接受多个连接
}
http {
sendfile on; # 启用零拷贝
tcp_nopush on; # 优化数据包发送
tcp_nodelay on; # 禁用Nagle算法
keepalive_timeout 30; # 长连接超时
keepalive_requests 1000; # 长连接最大请求数
# Gzip压缩
gzip on;
gzip_min_length 1k;
gzip_comp_level 4;
gzip_types text/plain text/css application/json application/javascript;
# 后端长连接
upstream backend {
server 192.168.1.10:8080;
keepalive 32; # 保持32个空闲长连接
}
server {
location / {
proxy_pass http://backend;
proxy_http_version 1.1; # 使用HTTP/1.1支持长连接
proxy_set_header Connection ""; # 清除Connection头
# 代理超时设置
proxy_connect_timeout 5s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
# 代理缓冲区
proxy_buffer_size 16k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
}
}
}
proxy_connect_timeout控制与后端建立连接的超时时间,proxy_send_timeout和proxy_read_timeout分别控制发送请求和读取响应的超时。合理设置这些参数可以防止后端故障时Nginx的worker进程被长时间阻塞。
六、SSL/TLS终结与HTTP/2
在Nginx层进行SSL终结,可以让后端服务器专注于业务逻辑处理:
server {
listen 443 ssl http2;
server_name api.example.com;
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets off;
# OCSP装订
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 valid=300s;
# HSTS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
location / {
proxy_pass http://backend;
}
}
# HTTP 跳转 HTTPS
server {
listen 80;
server_name api.example.com;
return 301 https://$host$request_uri;
}
启用ssl_session_cache可以大幅减少TLS握手开销,ssl_session_tickets用于会话恢复。TLS 1.3的0-RTT特性可以进一步减少延迟,但需要注意重放风险。
总结
Nginx反向代理的配置能力远超一般的Web服务器。通过合理的负载均衡策略、精细的限流配置、完善的健康检查机制以及深度的性能调优,Nginx能够为后端服务构建一道坚固高效的流量入口。在实际运维中,建议结合监控工具持续观察Nginx的运行指标,根据实际流量模式动态调整配置参数,使系统始终保持最佳状态。