Nginx速查手册
Nginx配置/反向代理/SSL/限流速查
🌐 server 虚拟主机
listen 端口、server_name 域名、root 站点根目录。
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example;
index index.html index.htm;
access_log /var/log/nginx/example.access.log;
error_log /var/log/nginx/example.error.log warn;
}
default_server 接管所有未匹配域名的请求,防止 IP 直连。
server {
listen 80 default_server;
server_name _;
return 444; # 直接断开,不返回内容
}
server {
listen 80;
server_name a.example.com;
root /var/www/a;
}
server {
listen 80;
server_name b.example.com ~^www\d+\.example\.com$; # 支持正则
root /var/www/b;
}
🎯 location 匹配
= 精确、^~ 前缀优先停止正则、~ 正则区分大小写、~* 不区分、普通前缀。
location = /favicon.ico { } # 精确匹配
location ^~ /static/ { } # 前缀匹配后不再尝试正则
location ~ \.php$ { } # 正则(区分大小写)
location ~* \.(png|jpg|gif|webp)$ { } # 正则(不区分大小写)
location /api/ { } # 普通前缀
location / { } # 兜底,所有请求最终落到这
= 命中即停 → ^~ 命中即停 → 正则按书写顺序第一个 → 最长普通前缀。
# 请求 /static/a.png 的选择过程:
# 1. location = 精确匹配?无
# 2. ^~ /static/ 命中 -> 直接使用,不再看正则
location ^~ /static/ { root /data; }
# 请求 /upload/x.PNG:
# 普通前缀先记下,再依次测试正则
# ~ \.png$ 不匹配大写;~* \.png$ 匹配 -> 使用正则块
location ~* \.png$ { add_header X-Type image; }
# 普通前缀之间取“最长”的一条,与书写顺序无关
📂 root / alias / index / try_files
root 把完整 URI 拼到根目录后;alias 用路径替换掉 location 前缀。
# 请求 /static/a.png -> /data/static/a.png
location /static/ {
root /data;
}
# 请求 /files/a.png -> /data/files/a.png
location /files/ {
alias /data/files/; # alias 末尾建议保留 /
}
# 正则 location 中 alias 需用捕获组
location ~ ^/img/(.+)$ {
alias /data/images/$1;
}
index 按顺序找默认文件;autoindex 列出目录(生产慎用)。
location / {
index index.html index.htm default.html;
}
location /downloads/ {
alias /data/downloads/;
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
}
按顺序检查文件/目录,最后一个参数作为兜底(SPA 必备)。
# Vue/React 单页应用:找不到文件交给前端路由
location / {
try_files $uri $uri/ /index.html;
}
# PHP 框架:交给 php-fpm
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# 都找不到明确返回 404
location /imgs/ {
try_files $uri $uri/ =404;
}
✏️ rewrite 与 return
能直接 return 就别 rewrite,效率最高;301 永久、302 临时。
# HTTP 整站跳 HTTPS
return 301 https://$host$request_uri;
# 单个旧路径
location = /old {
return 301 https://example.com/new;
}
location /maintain {
return 503;
}
# 返回纯文本/JSON
location = /health {
default_type application/json;
return 200 '{"status":"ok"}';
}
last 重新发起 location 匹配,break 在当前块结束重写。
# /article/123 -> /article.php?id=123(浏览器地址不变)
rewrite ^/article/(\d+)$ /article.php?id=$1 last;
# 旧目录整段永久跳转
rewrite ^/oldshop/(.*)$ https://shop.example.com/$1 permanent;
# last vs break
location /api/ {
rewrite ^/api/v1/(.*)$ /legacy/$1 break;
proxy_pass http://backend;
}
# if 尽量只配合 return/rewrite 使用(其他行为有坑)
if ($host !~* ^example\.com$) {
return 301 https://example.com$request_uri;
}
🔁 反向代理 proxy_pass
把真实客户端信息透传给后端;$host 保留原始域名。
location /api/ {
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_set_header X-Forwarded-Host $host;
proxy_connect_timeout 5s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
}
带 / 会替换掉 location 前缀;不带则保留完整 URI。
# 请求 /api/user
location /api/ {
proxy_pass http://127.0.0.1:8080;
# 后端收到:/api/user(原样保留)
}
location /api/ {
proxy_pass http://127.0.0.1:8080/;
# 后端收到:/user(/api/ 被替换成 /)
}
location /api {
proxy_pass http://127.0.0.1:8080;
# 不带 URI 模式:后端收到完整 /api/user
}
Upgrade/Connection 头支持 WS;SSE 需要关闭代理缓冲。
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 3600s;
}
# SSE / 流式响应
location /stream/ {
proxy_pass http://backend;
proxy_buffering off;
proxy_cache off;
proxy_set_header Connection "";
}
大文件下载建议关缓冲直接流式转发;重写后端跳转地址。
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 16k;
# 后端 302 Location 是内网地址时自动改写
proxy_redirect http://backend/ /;
# 上传大小与超时
client_max_body_size 100m;
client_body_buffer_size 1m;
# 透传/重写 Cookie 路径
proxy_cookie_path /admin/ /;
# 自定义响应头
add_header Cache-Control "no-cache" always;
⚖️ upstream 负载均衡
默认轮询;least_conn 最少连接,ip_hash 保持会话。
upstream backend {
server 10.0.0.1:8080;
server 10.0.0.2:8080;
}
proxy_pass http://backend;
upstream backend_lc {
least_conn;
server 10.0.0.1:8080;
server 10.0.0.2:8080;
}
upstream backend_hash {
ip_hash;
server 10.0.0.1:8080;
server 10.0.0.2:8080;
}
# 一致性 hash(nginx 1.7.2+)
upstream backend_ch {
hash $request_uri consistent;
server 10.0.0.1:8080;
}
weight 调比例,backup 兜底,max_fails/fail_timeout 做被动健康检查。
upstream backend {
server 10.0.0.1:8080 weight=3 max_fails=3 fail_timeout=30s;
server 10.0.0.2:8080 weight=1 max_fails=3 fail_timeout=30s;
server 10.0.0.3:8080 backup; # 前两台都挂才启用
server 10.0.0.9:8080 down; # 标记下线(灰度/维护)
}
到上游保持连接池,配合 HTTP/1.1 与清空 Connection 头降低开销。
upstream backend {
server 10.0.0.1:8080;
keepalive 64;
keepalive_timeout 60s;
keepalive_requests 1000;
}
server {
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
🔒 SSL / HTTPS
http2 直接写在 listen 后(1.25.1+ 用 http2 on;);证书+私钥成对。
server {
listen 443 ssl;
http2 on;
server_name example.com;
ssl_certificate /etc/nginx/ssl/example.com.pem; # 含中间证书
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:HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
}
80 端口只保留跳转与校验路径(如 acme 证书续签)。
server {
listen 80;
server_name example.com;
location ^~ /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://$host$request_uri;
}
}
确认整站 HTTPS 后再开 HSTS;always 保证错误响应也带头部。
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'; img-src * data:;" always;
🗜 gzip 压缩
放在 http 块全局生效;图片/视频等已压缩格式不必再压。
gzip on;
gzip_min_length 1k;
gzip_comp_level 5;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_vary on;
gzip_proxied any;
gzip_types
text/plain
text/css
text/xml
application/json
application/javascript
application/xml+rss
application/x-javascript
image/svg+xml;
# gzip_types 不含 text/html,默认已压缩
🚧 访问控制
按顺序匹配,第一条命中即决定;allow/deny 支持网段。
location /admin/ {
allow 10.0.0.0/8;
allow 192.168.1.5;
deny all;
}
# 封禁单个 IP
location / {
deny 1.2.3.4;
allow all;
}
# 只允许内网访问状态页
location = /nginx_status {
stub_status;
allow 127.0.0.1;
allow 10.0.0.0/8;
deny all;
}
点开头的配置/版本控制文件一律不对外。
location ~ /\.(git|svn|hg|env|htaccess) {
deny all;
return 404;
}
location ~* (composer\.(json|lock)|package(-lock)?\.json|\.bak|\.sql)$ {
deny all;
}
用 htpasswd 生成密码文件;satisfy any 可与 IP 白名单二选一。
# 生成密码文件(-c 首次创建,-b 命令行带密码)
# htpasswd -bc /etc/nginx/.htpasswd tom secret123
# htpasswd -b /etc/nginx/.htpasswd amy pass456
location /private/ {
auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/.htpasswd;
}
# IP 白名单与认证满足其一即可
# satisfy any;
📝 日志
http 块定义格式,server/location 引用;排障建议加 upstream 耗时。
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'rt=$request_time urt=$upstream_response_time '
'uaddr=$upstream_addr';
access_log /var/log/nginx/access.log main;
# JSON 日志,便于 ELK/Loki 采集
log_format json escape=json
'{"time":"$time_iso8601","ip":"$remote_addr",'
'"method":"$request_method","uri":"$request_uri",'
'"status":$status,"bytes":$body_bytes_sent}';
access_log /var/log/nginx/access.json.log json;
级别 debug/info/notice/warn/error;健康检查噪音可单独降级。
error_log /var/log/nginx/error.log warn;
location / {
# 该位置只记 error 以上,避免频繁 404 刷日志
error_log /var/log/nginx/fav.error.log error;
try_files $uri =404;
}
# access_log off; # 特定内部路径可关闭访问日志
# map $status $loggable { ~^[23] 0; default 1; }
# access_log path if=$loggable;
🚦 限流 limit_req / limit_conn
http 块定义共享内存区,rate 平均速率;burst 允许突发排队。
# 每个客户端 IP 平均 10 请求/秒,区域 10MB
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
server {
location /api/ {
limit_req zone=api burst=20 nodelay;
limit_req_status 429;
proxy_pass http://backend;
}
}
# nodelay:突发请求立即处理不排队排队延迟
# 去掉 nodelay:burst 部分按 rate 匀速放行
# delay=5:前 5 个突发立即,其余排队
防慢速攻击/单 IP 大量挂连接;可按 server 名维度限。
# 按 IP 限制并发连接
limit_conn_zone $binary_remote_addr zone=perip:10m;
# 按 server 限制总并发
limit_conn_zone $server_name zone=perserver:10m;
server {
limit_conn perip 20;
limit_conn perserver 1000;
limit_conn_status 503;
# 下载速度也可限(每连接 512KB/s)
location /download/ {
limit_rate 512k;
limit_rate_after 5m; # 前 5MB 不限速
}
}
🛠 运维命令与常用变量
改完配置先 -t 测试,再 reload 不停机生效。
nginx -t
nginx -T # 测试并打印全部生效配置
nginx -s reload
nginx -s stop / quit # stop 立即停 / quit 优雅停
systemctl reload nginx
systemctl status nginx
# 常用内置变量
# $remote_addr 客户端 IP(真实 IP 取 X-Forwarded-For/X-Real-IP)
# $host 请求 Host 头;$server_name 匹配到的域名
# $request_uri 完整原始 URI(含参数);$uri 解码规范化后的路径
# $args / $query_string 查询串;$scheme http 或 https
# $request_method 方法;$status 响应码;$http_referer
# $upstream_addr / $upstream_response_time 上游地址与耗时
😶 没有匹配的条目,换个关键词试试
📖 使用说明
全程在浏览器本地运行。
操作步骤:
- 搜索或浏览分类条目;
- 查看配置示例;
- 点击复制代码块。
💬 用户评论 (0)
还没有评论,快来抢沙发!