Nginx 配置最佳实践:从入门到精通
本文全面讲解 Nginx 的配置语法、常用场景、性能优化和安全加固,帮助运维和开发人员构建高性能、高可用的 Web 服务。
一、Nginx 基础架构 1.1 Nginx 工作原理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 graph TB A[客户端请求] --> B[Master 进程] B --> C[Worker 进程 1] B --> D[Worker 进程 2] B --> E[Worker 进程 N] C --> F[处理请求] D --> F E --> F F --> G[返回响应] style B fill:#ff6b6b style C fill:#4ecdc4 style D fill:#4ecdc4 style E fill:#4ecdc4
核心概念:
Master 进程 :管理 Worker 进程,处理配置加载、日志打开等
Worker 进程 :处理实际请求,多进程模型
事件驱动 :非阻塞 I/O,高并发性能
连接复用 :Keepalive 减少连接开销
1.2 安装 Nginx 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 apt update apt install nginx -y yum install epel-release -y yum install nginx -y wget http://nginx.org/download/nginx-1.24.0.tar.gz tar -zxvf nginx-1.24.0.tar.gz cd nginx-1.24.0./configure --prefix=/usr/local/nginx \ --with-http_ssl_module \ --with-http_stub_status_module \ --with-http_gzip_static_module make && make install nginx -v nginx -V systemctl start nginx systemctl stop nginx systemctl restart nginx systemctl reload nginx systemctl status nginx nginx -t nginx -T
1.3 目录结构 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 /etc/nginx/ ├── nginx.conf ├── mime.types ├── conf.d/ │ ├── default.conf │ └── example.com.conf ├── sites-available/ ├── sites-enabled/ ├── modules-available/ ├── modules-enabled/ ├── ssl/ ├── logs/ │ ├── access.log │ └── error.log └── conf/ ├── fastcgi.conf ├── koi-utf └── win-utf /var/www/ └── html/ └── index.html /var/log/nginx/ ├── access.log └── error.log
二、配置文件详解 2.1 nginx.conf 结构 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 user nginx; worker_processes auto; worker_rlimit_nofile 65535 ; error_log /var/log/nginx/error .log warn ; pid /var/run/nginx.pid; events { worker_connections 10240 ; use epoll ; multi_accept on ; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local ] "$request " ' '$status $body_bytes_sent "$http_referer " ' '"$http_user_agent " "$http_x_forwarded_for "' ; access_log /var/log/nginx/access.log main; sendfile on ; tcp_nopush on ; tcp_nodelay on ; keepalive_timeout 65 ; types_hash_max_size 2048 ; gzip on ; gzip_vary on ; gzip_proxied any; gzip_comp_level 6 ; gzip_types text/plain text/css text/xml application/json application/javascript application/xml; include /etc/nginx/conf.d/*.conf ; }
2.2 核心指令详解 worker_processes 1 2 3 4 5 6 7 8 worker_processes auto; worker_processes 4 ; worker_processes 1 ; worker_processes 4 ;worker_cpu_affinity 0001 0010 0100 1000 ;
worker_connections 1 2 3 4 5 6 7 events { worker_connections 10240 ; }
keepalive_timeout 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 http { keepalive_timeout 65 ; keepalive_requests 100 ; upstream backend { server 127.0.0.1:8080 ; keepalive 32 ; } server { location / { proxy_pass http://backend; proxy_http_version 1 .1 ; proxy_set_header Connection "" ; } } }
三、常用场景配置 3.1 静态文件服务器 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 44 45 46 47 48 49 50 51 server { listen 80 ; server_name example.com www.example.com; root /var/www/example.com; index index.html index.htm; access_log /var/log/nginx/example.com.access.log; error_log /var/log/nginx/example.com.error .log; location / { try_files $uri $uri / =404 ; } location ~* \.(jpg|jpeg|png|gif|ico|svg|webp)$ { expires 30d ; add_header Cache-Control "public, immutable" ; access_log off ; } location ~* \.(css|js)$ { expires 7d ; add_header Cache-Control "public" ; access_log off ; } location ~* \.(woff|woff2|ttf|eot|otf)$ { expires 30d ; add_header Cache-Control "public" ; access_log off ; } location ~ /\. { deny all; access_log off ; log_not_found off ; } location ~ ~$ { deny all; access_log off ; log_not_found off ; } }
3.2 反向代理 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 server { listen 80 ; server_name api.example.com; location / { proxy_pass http://127.0.0.1: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 ; proxy_connect_timeout 60s ; proxy_send_timeout 60s ; proxy_read_timeout 60s ; proxy_buffer_size 4k ; proxy_buffers 4 32k ; proxy_busy_buffers_size 64k ; proxy_temp_file_write_size 64k ; } location /ws/ { proxy_pass http://127.0.0.1:8080; proxy_http_version 1 .1 ; proxy_set_header Upgrade $http_upgrade ; proxy_set_header Connection "upgrade" ; proxy_set_header Host $host ; proxy_read_timeout 86400 ; } }
3.3 负载均衡 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 44 45 46 47 48 49 50 51 52 upstream backend { server 192.168.1.10:8080 ; server 192.168.1.11:8080 ; server 192.168.1.12:8080 ; keepalive 32 ; } server { listen 80 ; server_name app.example.com; location / { proxy_pass http://backend; proxy_http_version 1 .1 ; proxy_set_header Connection "" ; proxy_set_header Host $host ; proxy_set_header X-Real-IP $remote_addr ; proxy_connect_timeout 10s ; proxy_send_timeout 30s ; proxy_read_timeout 30s ; proxy_next_upstream error timeout http_500 http_502 http_503 http_504; proxy_next_upstream_tries 3 ; } }
3.4 HTTPS 配置 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 server { listen 443 ssl http2; server_name example.com www.example.com; ssl_certificate /etc/nginx/ssl/example.com.crt; ssl_certificate_key /etc/nginx/ssl/example.com.key; ssl_session_timeout 1d ; ssl_session_cache shared:SSL:50m ; ssl_session_tickets off ; ssl_protocols TLSv1.2 TLSv1.3 ; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers off ; ssl_stapling on ; ssl_stapling_verify on ; resolver 8.8.8.8 8.8.4.4 valid=300s ; resolver_timeout 5s ; add_header Strict-Transport-Security "max-age=63072000" always; root /var/www/example.com; index index.html; location / { try_files $uri $uri / =404 ; } } server { listen 80 ; server_name example.com www.example.com; return 301 https://$server_name $request_uri ; }
3.5 动静分离 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 upstream backend { server 127.0.0.1:8080 ; keepalive 32 ; } server { listen 80 ; server_name example.com; root /var/www/example.com; location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2)$ { expires 30d ; add_header Cache-Control "public, immutable" ; access_log off ; try_files $uri =404 ; } location / { proxy_pass http://backend; proxy_set_header Host $host ; proxy_set_header X-Real-IP $remote_addr ; proxy_http_version 1 .1 ; proxy_set_header Connection "" ; } location /api/ { 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 ; } }
四、性能优化 4.1 基础优化 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 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 user nginx;worker_processes auto;worker_rlimit_nofile 65535 ;events { worker_connections 10240 ; use epoll ; multi_accept on ; } http { sendfile on ; tcp_nopush on ; tcp_nodelay on ; keepalive_timeout 65 ; keepalive_requests 100 ; client_body_buffer_size 10M ; client_max_body_size 10M ; client_body_timeout 12 ; client_header_timeout 12 ; keepalive_timeout 15 ; send_timeout 10 ; gzip on ; gzip_vary on ; gzip_proxied any; gzip_comp_level 6 ; gzip_buffers 16 8k ; gzip_http_version 1 .1 ; gzip_min_length 256 ; gzip_types application/atom+xml application/geo+json application/javascript application/x-javascript application/json application/ld+json application/manifest+json application/rdf+xml application/rss+xml application/xhtml+xml application/xml font/eot font/otf font/ttf font/woff font/woff2 text/css text/javascript text/plain text/xml; }
4.2 缓存优化 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 proxy_cache_path /var/cache/nginx levels=1 :2 keys_zone=my_cache:100m 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_key $scheme $request_method $host $request_uri ; proxy_cache_valid 200 302 10m ; proxy_cache_valid 404 1m ; proxy_cache_methods GET HEAD; add_header X-Cache-Status $upstream_cache_status ; proxy_cache_bypass $http_pragma $http_authorization ; proxy_no_cache $http_pragma $http_authorization ; } location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ { expires 30d ; add_header Cache-Control "public, immutable" ; access_log off ; } }
4.3 连接优化 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 http { open_file_cache max=100000 inactive=20s ; open_file_cache_valid 30s ; open_file_cache_min_uses 2 ; open_file_cache_errors on ; reset_timedout_connection on ; server_names_hash_bucket_size 128 ; server_names_hash_max_size 4096 ; types_hash_max_size 2048 ; types_hash_bucket_size 64 ; limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s; limit_conn_zone $binary_remote_addr zone=addr:10m ; server { listen 80 ; server_name example.com; location / { limit_req zone=one burst=20 nodelay; limit_conn addr 10 ; proxy_pass http://backend; } location /api/ { limit_req zone=one burst=5 nodelay; limit_conn addr 5 ; proxy_pass http://backend; } } }
4.4 FastCGI 优化(PHP) 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 server { listen 80 ; server_name example.com; root /var/www/html; index index.php index.html; location ~ \.php$ { fastcgi_pass unix:/run/php/php-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root $fastcgi_script_name ; include fastcgi_params; fastcgi_cache_path /var/cache/nginx/fastcgi levels=1 :2 keys_zone=php_cache:100m max_size=1g inactive=60m ; fastcgi_cache php_cache; fastcgi_cache_key $request_method $host $fastcgi_script_name $query_string ; fastcgi_cache_valid 200 30m ; fastcgi_cache_valid 404 1m ; fastcgi_cache_use_stale error timeout invalid_header http_500; fastcgi_cache_bypass $skip_cache ; fastcgi_no_cache $skip_cache ; fastcgi_buffer_size 128k ; fastcgi_buffers 256 16k ; fastcgi_busy_buffers_size 256k ; fastcgi_temp_file_write_size 256k ; fastcgi_connect_timeout 60s ; fastcgi_send_timeout 180s ; fastcgi_read_timeout 180s ; } }
五、安全加固 5.1 基础安全配置 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 44 45 46 47 48 49 50 51 52 server { listen 80 ; server_name example.com; server_tokens off ; 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 "strict-origin-when-cross-origin" always; add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';" always; add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always; location ~ /\. { deny all; access_log off ; log_not_found off ; } location ~ ~$ { deny all; access_log off ; log_not_found off ; } location ~* \.(git|svn|htaccess|htpasswd|ini|log|sh|sql|conf|bak|swp)$ { deny all; access_log off ; log_not_found off ; } location ~* \.(bak|backup|old|orig|save|tmp|temp)$ { deny all; access_log off ; log_not_found off ; } if ($request_method !~ ^(GET|HEAD|POST|PUT|DELETE|OPTIONS)$) { return 405 ; } client_max_body_size 10M ; large_client_header_buffers 4 16k ; }
5.2 DDoS 防护 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 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 http { limit_conn_zone $binary_remote_addr zone=addr:10m ; limit_conn_zone $server_name zone=server:10m ; limit_req_zone $binary_remote_addr zone=req:10m rate=10r/s; limit_req_zone $binary_remote_addr zone=api:10m rate=5r/s; client_body_buffer_size 10M ; client_max_body_size 10M ; client_body_timeout 10s ; client_header_timeout 10s ; keepalive_timeout 15s ; send_timeout 10s ; server { listen 80 ; server_name example.com; location / { limit_conn addr 10 ; limit_conn server 1000 ; limit_req zone=req burst=20 nodelay; proxy_pass http://backend; } location /api/ { limit_conn addr 5 ; limit_req zone=api burst=5 nodelay; proxy_pass http://backend; } location /login { limit_req zone=api burst=3 nodelay; proxy_pass http://backend; } location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ { limit_conn addr 20 ; limit_req zone=req burst=50 ; expires 30d ; access_log off ; } } } http { limit_req_status 429 ; limit_conn_status 429 ; server { error_page 429 /429 .html; location = /429 .html { root /var/www/error_pages; internal; } } }
5.3 SSL/TLS 安全 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 server { listen 443 ssl http2; server_name example.com; ssl_certificate /etc/nginx/ssl/example.com.crt; ssl_certificate_key /etc/nginx/ssl/example.com.key; ssl_protocols TLSv1.2 TLSv1.3 ; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers off ; ssl_session_timeout 1d ; ssl_session_cache shared:SSL:50m ; 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 ; add_header Strict-Transport-Security "max-age=63072000" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; }
5.4 访问控制 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 44 45 46 47 48 49 50 51 server { listen 80 ; server_name example.com; location /admin/ { allow 192.168.1.0 /24 ; allow 10.0.0.0 /8 ; deny all; proxy_pass http://backend; } location /private/ { auth_basic "Restricted Area" ; auth_basic_user_file /etc/nginx/.htpasswd; proxy_pass http://backend; } if ($http_user_agent ~* (curl|wget|scrapy|python-requests)) { return 403 ; } location ~* \.(jpg|jpeg|png|gif)$ { valid_referers none blocked server_names *.example.com ; if ($invalid_referer ) { return 403 ; } } }
六、监控与日志 6.1 日志配置 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 http { log_format main '$remote_addr - $remote_user [$time_local ] "$request " ' '$status $body_bytes_sent "$http_referer " ' '"$http_user_agent " "$http_x_forwarded_for " ' 'rt=$request_time uct="$upstream_connect_time " ' 'uht="$upstream_header_time " urt="$upstream_response_time "' ; log_format json escape=json '{' '"time_local":"$time_local ",' '"remote_addr":"$remote_addr ",' '"request":"$request ",' '"status": $status ,' '"body_bytes_sent":$body_bytes_sent ,' '"request_time":$request_time ,' '"upstream_response_time":"$upstream_response_time ",' '"http_referer":"$http_referer ",' '"http_user_agent":"$http_user_agent "' '}' ; access_log /var/log/nginx/access.log main; error_log /var/log/nginx/error .log warn ; server { listen 80 ; server_name example.com; access_log /var/log/nginx/example.com.access.log main; error_log /var/log/nginx/example.com.error .log warn ; } map $status $loggable { ~^[23] 0; default 1 ; } access_log /var/log/nginx/errors.log main if=$loggable ; }
6.2 日志分析 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 tail -f /var/log/nginx/access.logawk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20 awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20 awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn grep " 404 " /var/log/nginx/access.log awk '($10 > 1) {print $7, $10}' /var/log/nginx/access.log goaccess /var/log/nginx/access.log -o report.html --log-format=COMBINED awk '{print $1}' access.log | sort | uniq -c | sort -nr | head -10
6.3 状态监控 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 http { server { listen 80 ; server_name localhost; location /nginx_status { stub_status on ; access_log off ; allow 127.0.0.1 ; allow 192.168.1.0 /24 ; deny all; } location /health { access_log off ; return 200 "healthy\n" ; add_header Content-Type text/plain; } } } curl http://localhost/nginx_status
6.4 Prometheus 监控 1 2 3 4 5 6 7 8 9 10 11 12 13 14 docker run -p 9113 :9113 nginx/nginx-prometheus-exporter:latest \ -nginx.scrape-uri="http://localhost/nginx_status" scrape_configs: - job_name: 'nginx' static_configs: - targets: ['localhost:9113' ]
七、故障排查 7.1 常见问题 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 nginx -t nginx -T nginx -s reload ps aux | grep nginx netstat -tlnp | grep nginx ss -tlnp | grep nginx tail -f /var/log/nginx/error.logtail -f /var/log/nginx/access.loglsof -p $(cat /var/run/nginx.pid) top -p $(cat /var/run/nginx.pid) curl -I http://localhost curl -v http://localhost
7.2 错误码排查
错误码
含义
常见原因
解决方案
400
错误请求
请求格式错误
检查客户端请求
403
禁止访问
权限不足
检查文件权限、IP 限制
404
未找到
文件不存在
检查路径、root 配置
405
方法不允许
HTTP 方法错误
检查允许的请求方法
413
请求体过大
超过限制
调整 client_max_body_size
414
URI 过长
URL 太长
调整 large_client_header_buffers
499
客户端关闭
客户端超时
优化后端响应时间
500
服务器错误
配置错误
检查 error.log
502
错误网关
后端服务异常
检查后端服务状态
503
服务不可用
后端过载
检查后端负载
504
网关超时
后端响应超时
增加 proxy_read_timeout
7.3 调试技巧 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 error_log /var/log/nginx/error .log debug ;error_log /var/log/nginx/error .log debug_http;error_log /var/log/nginx/error .log debug_upstream;location /debug { return 200 " remote_addr: $remote_addr remote_user: $remote_user request: $request uri: $uri args: $args request_method: $request_method content_type: $content_type content_length: $content_length host: $host http_host: $http_host server_protocol: $server_protocol " ; add_header Content-Type text/plain; }
八、总结 Nginx 配置的关键要点:
基础配置 :worker_processes、worker_connections、keepalive
常用场景 :静态文件、反向代理、负载均衡、HTTPS
性能优化 :缓存、压缩、连接优化
安全加固 :隐藏版本、安全头、访问控制、DDoS 防护
监控日志 :日志格式、状态监控、故障排查
记住:配置要简洁,优化要适度,安全要优先 。
参考资料: