一、高级配置技巧
1. 动态分流与灰度发布
使用 split_clients 模块实现按比例分流请求,常用于 AB 测试或灰度发布:
split_clients "${remote_addr}AAA" $variant {
50% "backend_v1";
50% "backend_v2";
}
location / {
proxy_pass http://$variant;
}
2. 条件映射请求头
利用 map 指令动态设置变量,例如根据 User-Agent 分类请求:
map $http_user_agent $is_mobile {
default 0;
"~*android|iphone" 1;
}
server {
if ($is_mobile) {
rewrite ^ /mobile redirect;
}
}
3. 动态生成响应内容
无需后端,直接通过 Nginx 返回内容:
location /hello {
add_header Content-Type text/plain;
return 200 "Hello, World!\nHost: $host\nURI: $request_uri";
}
二、性能优化
1. TCP 连接复用
提升反向代理性能,复用后端连接:
upstream backend {
server 10.0.0.1:80;
keepalive 32; # 保持长连接
}
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
2. 静态文件高效传输
启用内存缓存和零拷贝技术:
sendfile on;
tcp_nopush on; # 数据包累积到一定大小再发送
tcp_nodelay on; # 禁用 Nagle 算法
aio on; # 异步文件读取(需 Linux 内核支持)
3. 动态压缩优化
精细控制 Gzip 压缩,避免压缩小文件:
gzip on;
gzip_min_length 1024; # 小于 1KB 不压缩
gzip_comp_level 5;
gzip_types text/plain application/json;
三、安全增强
1. 请求频率限制
防御暴力攻击,限制同一 IP 的请求速率:
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
proxy_pass http://backend;
}
2. 敏感路径隐藏
通过随机化路径防止扫描:
location ~ ^/admin-(?!xyz123)[a-zA-Z0-9]+$ {
# 仅当路径包含 "xyz123" 时才允许访问
proxy_pass http://backend_admin;
}
3. 安全头配置
强制安全策略:
add_header X-Content-Type-Options "nosniff";
add_header Content-Security-Policy "default-src 'self'";
add_header X-Frame-Options "DENY";
四、调试与日志
1. 条件日志记录
仅记录特定请求(如 POST 或错误状态码):
map $request_method $loggable {
default 0;
POST 1;
}
map $status $log_status {
~^[45] 1;
default 0;
}
access_log /var/log/nginx/important.log combined if=$loggable;
access_log /var/log/nginx/errors.log combined if=$log_status;
2. 实时调试变量
输出变量值到响应头,方便调试:
add_header X-Debug-Host "$host";
add_header X-Debug-Remote-IP "$remote_addr";
五、四层代理与 UDP
Nginx 的 stream 模块支持 TCP/UDP 代理(如数据库负载均衡):
stream {
upstream dns_servers {
server 10.0.0.1:53;
server 10.0.0.2:53;
}
server {
listen 53 udp;
proxy_pass dns_servers;
}
}
六、实用冷知识
-
优雅关闭 Worker 进程
向旧进程发送SIGQUIT,处理完当前请求后退出:kill -QUIT `cat /run/nginx.pid` -
复用配置变量
用set定义变量简化复杂逻辑:set $cache_key "$host$request_uri"; proxy_cache_key $cache_key; -
GeoIP 拦截
根据地理位置拒绝访问(需ngx_http_geoip_module):geoip_country /etc/nginx/GeoIP.dat; location / { if ($geoip_country_code = CN) { return 403; } }
七、注意事项
- 慎用
if指令:在location中使用if可能导致性能问题,优先使用map或split_clients。 - 缓存失效:动态内容避免过度缓存,可通过
proxy_cache_bypass控制。 - 正则优化:正则匹配(如
~*)较耗时,尽量在location外层过滤。
以上技巧可根据场景组合使用,建议结合官方文档和实际需求调整参数。