Nginx 反向代理的性能优化
Nginx 作为反向代理在我们的架构中承担着重要角色。从单机几千 QPS 到集群处理十万级并发,我在 Nginx 调优方面积累了不少经验。这里分享一些实战中验证有效的优化策略。
基础性能调优
worker 进程配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| user nginx; worker_processes auto;
worker_cpu_affinity auto;
events { worker_connections 65535; use epoll; multi_accept on; }
worker_rlimit_nofile 100000;
|
连接处理优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| http { keepalive_timeout 60s; keepalive_requests 10000;
client_max_body_size 10m; client_body_timeout 10s; client_header_timeout 10s;
send_timeout 10s; sendfile on; tcp_nopush on; tcp_nodelay on; }
|
反向代理优化
upstream 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| upstream backend_pool { least_conn;
server 192.168.1.10:8080 weight=3 max_fails=2 fail_timeout=10s; server 192.168.1.11:8080 weight=3 max_fails=2 fail_timeout=10s; server 192.168.1.12:8080 weight=2 max_fails=2 fail_timeout=10s backup;
keepalive 300; keepalive_requests 1000; keepalive_timeout 60s; }
server { listen 80; server_name api.example.com;
location /api/ { proxy_pass http://backend_pool;
proxy_http_version 1.1; proxy_set_header Connection ""; proxy_connect_timeout 5s; proxy_read_timeout 30s; proxy_send_timeout 30s;
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_buffering on; proxy_buffer_size 8k; proxy_buffers 8 8k; proxy_busy_buffers_size 16k; } }
|
实战案例:API 网关优化
问题现象:高峰期 API 响应时间 P99 超过 3 秒,Nginx error log 出现大量 upstream timeout
分析过程:
1 2 3 4 5 6 7 8 9
| curl http://localhost/nginx_status
tail -f /var/log/nginx/error.log | grep timeout
|
优化方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| upstream api_servers { server 10.0.1.10:8080 weight=5 max_fails=3 fail_timeout=30s; server 10.0.1.11:8080 weight=5 max_fails=3 fail_timeout=30s; server 10.0.1.12:8080 weight=5 max_fails=3 fail_timeout=30s; server 10.0.1.13:8080 weight=3 max_fails=3 fail_timeout=30s;
keepalive 500; keepalive_requests 10000; }
location /api/ { proxy_pass http://api_servers;
proxy_connect_timeout 3s; proxy_read_timeout 60s; proxy_send_timeout 60s;
proxy_http_version 1.1; proxy_set_header Connection "";
proxy_buffering on; proxy_buffer_size 16k; proxy_buffers 16 16k; proxy_busy_buffers_size 32k; }
|
效果:P99 延迟降到 500ms,错误率从 5%降到 0.1%
缓存策略优化
静态文件缓存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ { expires 1y; add_header Cache-Control "public, immutable"; add_header Vary "Accept-Encoding";
gzip on; gzip_vary on; gzip_comp_level 6; gzip_types text/plain text/css text/xml text/javascript application/javascript application/json application/xml+rss; }
|
API 响应缓存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| proxy_cache_path /var/cache/nginx/api levels=1:2 keys_zone=api_cache:100m max_size=10g inactive=60m use_temp_path=off;
server { location /api/static/ { proxy_pass http://backend_pool;
proxy_cache api_cache; proxy_cache_key "$scheme$request_method$host$request_uri"; proxy_cache_valid 200 302 10m; proxy_cache_valid 404 1m; proxy_cache_valid any 5m;
proxy_cache_use_stale error timeout invalid_header updating; proxy_cache_lock on; proxy_cache_lock_timeout 3s;
add_header X-Cache-Status $upstream_cache_status; } }
|
限流和安全优化
请求限制配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| http { limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s; limit_req_zone $server_name zone=perserver:10m rate=1000r/s;
limit_conn_zone $binary_remote_addr zone=addr:10m;
server { limit_req zone=api burst=20 nodelay; limit_req zone=perserver burst=100; limit_conn addr 10;
client_body_timeout 10s; client_max_body_size 10m; limit_rate_after 1m; limit_rate 500k;
location /api/ { limit_req zone=api burst=5 nodelay; proxy_pass http://backend_pool; } } }
|
安全头配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| server { add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; add_header Referrer-Policy "no-referrer-when-downgrade" always; add_header Content-Security-Policy "default-src 'self'" always;
server_tokens off;
if ($request_method !~ ^(GET|HEAD|POST)$) { return 405; }
location ~ /\. { deny all; } }
|
监控和日志优化
访问日志格式
1 2 3 4 5 6 7 8 9 10 11 12
| log_format main_ext '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' '$request_time $upstream_response_time ' '$upstream_addr $upstream_status';
access_log /var/log/nginx/access.log main_ext buffer=64k flush=1m;
error_log /var/log/nginx/error.log warn;
|
性能监控配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| server { listen 127.0.0.1:80; server_name localhost;
location /nginx_status { stub_status on; access_log off; allow 127.0.0.1; deny all; }
location /status { vhost_traffic_status_display; vhost_traffic_status_display_format html; access_log off; } }
|
高级优化技巧
SSL 优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| server { listen 443 ssl http2;
ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/key.pem;
ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512; ssl_prefer_server_ciphers off; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; ssl_session_tickets off;
ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 5s; }
|
动态 upstream
1 2 3 4 5 6 7 8 9 10 11
| upstream dynamic_backend { zone backend 64k;
server backend1.example.com service=backend weight=5; server backend2.example.com service=backend weight=5;
health_check interval=5s fails=3 passes=2 uri=/health; }
|
自动化配置管理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| #!/bin/bash
BACKEND_SERVERS=$(curl -s http://consul:8500/v1/health/service/api-server | jq -r '.[] | select(.Checks[].Status == "passing") | .Service.Address + ":" + (.Service.Port | tostring)')
cat > /etc/nginx/conf.d/upstream.conf << EOF upstream backend_pool { least_conn; keepalive 300; EOF
for server in $BACKEND_SERVERS; do echo " server $server weight=1 max_fails=2 fail_timeout=10s;" >> /etc/nginx/conf.d/upstream.conf done
echo "}" >> /etc/nginx/conf.d/upstream.conf
if nginx -t; then nginx -s reload echo "Nginx configuration updated successfully" else echo "Nginx configuration test failed" exit 1 fi
|
性能测试验证
基准测试脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| #!/bin/bash
URL="http://localhost/api/test" CONCURRENCY=100 REQUESTS=10000
echo "Testing Nginx performance..."
ab -n $REQUESTS -c $CONCURRENCY -k $URL
wrk -t12 -c400 -d30s --latency $URL
while true; do curl -s http://localhost/nginx_status sleep 5 done
|
通过系统性的性能优化,Nginx 反向代理可以轻松处理数万并发连接。关键是要根据实际业务场景调整配置参数,并建立完善的监控体系来持续优化。记住,优化是一个迭代的过程,需要不断测试和调整。