Nginx 是绝大多数 Web 架构的入口。配置得当,它是铜墙铁壁;配置粗糙,它就是性能瓶颈和安全隐患。本文是一份实战导向的速查手册,覆盖从初次部署到生产调优的全链路。
一、基础结构速览
Nginx 的配置由指令(directive)和块(block)组成,层级关系决定作用域。
主配置文件: /etc/nginx/nginx.conf 站点配置: /etc/nginx/conf.d/*.conf 或 /etc/nginx/sites-enabled/*
├── main # 全局:worker 进程、日志、pid
│ ├── events # 连接处理模型
│ └── http # HTTP 协议相关
│ ├── upstream # 后端服务器组
│ ├── server # 虚拟主机(站点)
│ │ └── location # URL 路径匹配
│ └── map # 变量映射核心概念
快速操作
# 测试配置语法
nginx -t
# 重新加载(不中断连接)
nginx -s reload
# 查看编译参数和模块
nginx -V
# 查看生效的完整配置
nginx -T二、虚拟主机配置
2.1 静态站点
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example.com;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}2.2 匹配规则与优先级
匹配优先级:= > ^~ > ~ / ~* > /
三、反向代理与负载均衡
3.1 基础反向代理
upstream backend {
server 127.0.0.1:3000;
server 127.0.0.1:3001;
}
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;
proxy_connect_timeout 5s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
}
}3.2 负载均衡策略
3.3 WebSocket 代理
location /ws {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s;
}四、HTTPS 与安全加固
4.1 基础 HTTPS
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
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;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
resolver 8.8.8.8 1.1.1.1 valid=300s;
}
# HTTP -> HTTPS 强制跳转
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}4.2 安全 Headers
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 Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;4.3 敏感路径防护
# 禁止访问隐藏文件(.git、.env 等)
location ~ /\. {
deny all;
return 404;
}
# 禁止访问备份文件
location ~* \.(bak|sql|log|conf)$ {
deny all;
}
# 限制特定 IP 访问管理后台
location /admin/ {
allow 10.0.0.0/8;
allow 192.168.0.0/16;
deny all;
proxy_pass http://backend;
}五、性能调优
5.1 Worker 进程与连接
worker_processes auto;
worker_rlimit_nofile 65535;
events {
use epoll;
worker_connections 10240;
multi_accept on;
}5.2 HTTP 层优化
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 30s;
keepalive_requests 100;
client_max_body_size 50m;
client_body_buffer_size 128k;
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 4;
gzip_min_length 256;
gzip_types
text/plain
text/css
text/javascript
application/json
application/javascript
application/xml
application/xml+rss
image/svg+xml;
}5.3 静态资源优化
# 图片等静态资源 — 长期缓存
location ~* \.(jpg|jpeg|png|gif|ico|webp|avif)$ {
expires 365d;
add_header Cache-Control "public, immutable";
access_log off;
}
# CSS/JS/字体
location ~* \.(css|js|woff2?|ttf|eot)$ {
expires 365d;
add_header Cache-Control "public, immutable";
access_log off;
}
# HTML — 每次验证
location ~* \.(html|htm)$ {
add_header Cache-Control "no-cache, must-revalidate";
}六、缓存策略
6.1 代理缓存
http {
proxy_cache_path /var/cache/nginx
levels=1:2
keys_zone=app_cache:10m
max_size=1g
inactive=60m
use_temp_path=off;
}
server {
location / {
proxy_pass http://backend;
proxy_cache app_cache;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503;
proxy_cache_lock on;
proxy_cache_lock_timeout 5s;
add_header X-Cache-Status $upstream_cache_status;
}
}$upstream_cache_status 值说明:MISS -> HIT -> EXPIRED -> STALE -> UPDATING -> BYPASS
6.2 按条件缓存
# 不缓存 POST 请求
proxy_cache_methods GET HEAD;
# 不缓存包含特定 Cookie 的请求
proxy_cache_bypass $cookie_session;
proxy_no_cache $cookie_session;
# 按 URL 参数跳过缓存
proxy_cache_bypass $arg_nocache;七、日志与监控
7.1 自定义日志格式
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time';
log_format json escape=json '{'
'"time":"$time_iso8601",'
'"remote_addr":"$remote_addr",'
'"method":"$request_method",'
'"uri":"$request_uri",'
'"status":$status,'
'"body_bytes":$body_bytes_sent,'
'"request_time":$request_time,'
'"upstream_time":"$upstream_response_time"'
'}';7.2 状态监控
location /nginx_status {
stub_status;
allow 127.0.0.1;
deny all;
}7.3 日志切割
# /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 $(cat /var/run/nginx.pid)
endscript
}八、常见问题排查
8.1 502 Bad Gateway
curl -I http://127.0.0.1:3000
tail -f /var/log/nginx/error.log常见原因:
后端服务挂了 -> 重启后端
proxy_pass 地址写错 -> 核对 upstream
连接超时太短 -> 增大 proxy_connect_timeout
文件描述符耗尽 -> 调大 worker_rlimit_nofile
8.2 413 Request Entity Too Large
client_max_body_size 100m; # 默认 1m,按需调大8.3 504 Gateway Timeout
proxy_read_timeout 120s; # 默认 60s
proxy_send_timeout 120s;8.4 配置不生效
nginx -t # 检查语法
nginx -T | grep "你的指令" # 查看实际加载的配置
ps aux | grep nginx # 确认进程已更新8.5 跨域问题
location /api/ {
add_header Access-Control-Allow-Origin * always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
add_header Access-Control-Allow-Headers "Authorization, Content-Type" always;
if ($request_method = 'OPTIONS') {
return 204;
}
proxy_pass http://backend;
}九、生产配置模板
主配置 /etc/nginx/nginx.conf
user www-data;
worker_processes auto;
worker_rlimit_nofile 65535;
pid /run/nginx.pid;
events {
use epoll;
worker_connections 10240;
multi_accept on;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
types_hash_max_size 2048;
server_tokens off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
keepalive_timeout 30s;
keepalive_requests 100;
client_max_body_size 50m;
client_body_buffer_size 128k;
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 4;
gzip_min_length 256;
gzip_types text/plain text/css text/javascript application/json
application/javascript application/xml image/svg+xml;
log_format json escape=json '{'
'"time":"$time_iso8601",'
'"remote_addr":"$remote_addr",'
'"method":"$request_method",'
'"uri":"$request_uri",'
'"status":$status,'
'"body_bytes":$body_bytes_sent,'
'"request_time":$request_time,'
'"upstream_time":"$upstream_response_time"'
'}';
access_log /var/log/nginx/access.log json buffer=32k flush=5s;
error_log /var/log/nginx/error.log warn;
proxy_cache_path /var/cache/nginx
levels=1:2
keys_zone=app_cache:10m
max_size=1g
inactive=60m
use_temp_path=off;
include /etc/nginx/conf.d/*.conf;
}站点配置 /etc/nginx/conf.d/example.conf
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
access_log /var/log/nginx/example.access.log json buffer=32k flush=5s;
error_log /var/log/nginx/example.error.log warn;
location ~* \.(jpg|jpeg|png|gif|ico|webp|css|js|woff2?)$ {
root /var/www/example.com;
expires 365d;
add_header Cache-Control "public, immutable";
access_log off;
}
location /api/ {
proxy_pass http://127.0.0.1:3000;
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 5s;
proxy_read_timeout 60s;
proxy_cache app_cache;
proxy_cache_valid 200 10m;
proxy_cache_use_stale error timeout updating;
add_header X-Cache-Status $upstream_cache_status;
}
location / {
root /var/www/example.com/dist;
try_files $uri $uri/ /index.html;
}
location ~ /\. {
deny all;
return 404;
}
}附:上线检查清单
nginx -t配置语法无报错server_tokens off已关闭版本暴露HTTPS 已启用,HTTP 已跳转
TLS 仅启用 1.2+,HSTS 已配置
安全 Headers 齐全(X-Frame-Options 等)
隐藏文件(.git、.env)已禁止访问
client_max_body_size按业务设置合理值gzip 已开启,排除已压缩格式
静态资源已设置长期缓存 + immutable
日志格式包含 request_time 和 upstream_response_time
error_log 级别为 warn(生产不要用 debug)
代理超时已按业务场景调整
本文是「服务器运维笔记」系列第 2 篇。