第 210 章:Nginx 进阶配置
学习目标
- 掌握 location 匹配规则
- 学会多级缓存
- 配置防盗链与跨域
- 实现灰度发布
一、location 匹配规则
nginx
location [modifier] pattern {
...
}| modifier | 匹配方式 | 优先级 |
|---|---|---|
= | 精确 | 1(最高) |
^~ | 前缀,匹配后不再正则 | 2 |
~ | 正则(区分大小写) | 3 |
~* | 正则(不区分大小写) | 3 |
| (无) | 前缀 | 4(最低) |
例子
nginx
# 1. 精确 =
location = /login {
return 200 "登录页";
}
# 2. 前缀(优先)
location ^~ /static/ {
root /var/www;
}
# 3. 正则
location ~ \.(gif|jpg|png)$ {
expires 30d;
}
location ~* \.(GIF|JPG)$ {
# 同上,不区分大小写
}
# 4. 普通前缀
location /api {
proxy_pass http://backend;
}匹配示例:
GET /static/img.jpg
→ ^~ /static/ 命中 (前缀优先)GET /login
→ = /login 命中 (精确优先)二、URL 重写
2.1 rewrite
nginx
location /old {
rewrite ^/old/(.*)$ /new/$1 permanent; # 301
}
location /api {
rewrite ^/api/(.*)$ /$1 break;
}2.2 return
nginx
location /admin {
return 403;
}
location /google {
return 301 https://www.google.com;
}2.3 try_files
nginx
location / {
try_files $uri $uri/ /index.html;
# 找不到 $uri → 找 $uri/ 目录 → fallback 到 /index.html
}
location /static {
try_files $uri =404;
}三、防盗链
nginx
location ~* \.(jpg|jpeg|png|gif|webp)$ {
valid_referers none blocked *.example.com example.com;
if ($invalid_referer) {
return 403;
}
}四、跨域 CORS
nginx
location /api/ {
# 允许的源
add_header Access-Control-Allow-Origin "https://example.com" always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
add_header Access-Control-Allow-Credentials "true" always;
add_header Access-Control-Max-Age 86400;
# OPTIONS 直接 204
if ($request_method = OPTIONS) {
return 204;
}
proxy_pass http://backend;
}五、灰度发布
5.1 基于 Cookie
nginx
upstream backend_v1 {
server 192.168.1.1:3000;
}
upstream backend_v2 {
server 192.168.1.2:3000;
}
server {
location / {
# 灰度用户(cookie 中带 beta=1)到 v2
if ($cookie_beta = "1") {
proxy_pass http://backend_v2;
}
# 默认 v1
proxy_pass http://backend_v1;
}
}5.2 基于权重
nginx
upstream backend {
server 192.168.1.1:3000 weight=9; # 90% 到 v1
server 192.168.1.2:3000 weight=1; # 10% 到 v2
}5.3 基于 IP
nginx
geo $gray_release {
default 0;
192.168.1.0/24 1; # 内部 IP 灰度
10.0.0.0/8 1;
}
server {
location / {
if ($gray_release = 1) {
proxy_pass http://backend_v2;
}
proxy_pass http://backend_v1;
}
}六、动静分离
nginx
server {
# 静态资源
location ~* \.(html|css|js|jpg|png|gif|ico|woff|ttf)$ {
root /var/www/static;
expires 30d;
access_log off;
}
# API 走后端
location /api/ {
proxy_pass http://backend;
}
}七、多级缓存
nginx
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=cache_static:10m
max_size=10g inactive=30d use_temp_path=off;
server {
location / {
proxy_pass http://backend;
proxy_cache cache_static;
# 不同状态码不同缓存
proxy_cache_valid 200 10m;
proxy_cache_valid 301 1h;
proxy_cache_valid 404 1m;
proxy_cache_valid any 5s;
# 缓存条件
proxy_cache_methods GET HEAD;
proxy_cache_min_uses 2; # 至少被请求 2 次才缓存
proxy_cache_key "$scheme$host$request_uri";
# 命中状态
add_header X-Cache-Status $upstream_cache_status;
# 绕过条件
proxy_cache_bypass $http_cache_control;
}
}主动清理缓存
bash
# 删除指定 key
rm -rf /var/cache/nginx/c/3a/1234567890abc...或使用 ngx_cache_purge 模块:
nginx
location ~ /purge(/.*) {
proxy_cache_purge cache_static $scheme$host$1;
}八、安全加固
8.1 安全头
nginx
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;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}8.2 限制请求体大小
nginx
client_max_body_size 10M;8.3 隐藏版本号
nginx
server_tokens off;8.4 限速
nginx
http {
limit_req_zone $binary_remote_addr zone=global:10m rate=10r/s;
server {
location / {
limit_req zone=global burst=20 nodelay;
limit_req_status 429;
}
}
}8.5 阻止常见攻击
nginx
# 阻止常见 User-Agent
if ($http_user_agent ~* "scrapy|curl|wget|bot") {
return 403;
}
# 阻止特定文件
location ~ /\.(git|svn|env) {
deny all;
}九、WebSocket
nginx
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
location /ws/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
}
}十、监控
10.1 状态页
nginx
location /nginx_status {
stub_status;
allow 127.0.0.1;
deny all;
}Active connections: 2
server accepts handled requests
100 100 200
Reading: 0 Writing: 1 Waiting: 110.2 Prometheus exporter
bash
nginx_exporter -nginx.scrape-uri=http://localhost/nginx_status十一、常见问题
11.1 配置不生效
bash
nginx -t # 测试语法
nginx -s reload # 重载11.2 502 Bad Gateway
- 后端服务没启动
- 端口被防火墙挡
proxy_pass配置错
11.3 跨域头重复
后端已经设置 CORS 头,前端再添加会重复。
解决:删一个,推荐只在前端 Nginx 设置。
11.4 大文件上传
nginx
client_max_body_size 100M;
client_body_buffer_size 128k;
proxy_read_timeout 300s;十二、生产配置模板
nginx
user nginx;
worker_processes auto;
worker_rlimit_nofile 65535;
events {
worker_connections 4096;
use epoll;
multi_accept on;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
charset utf-8;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 30;
keepalive_requests 100;
server_tokens off;
client_max_body_size 50M;
gzip on;
gzip_vary on;
gzip_min_length 1k;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
# 日志
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'rt=$request_time uct=$upstream_connect_time urt=$upstream_response_time';
access_log /var/log/nginx/access.log main;
# 限流
limit_req_zone $binary_remote_addr zone=api:10m rate=30r/s;
include /etc/nginx/conf.d/*.conf;
}十三、本章小结
| 技巧 | 用途 |
|---|---|
| location 规则 | URL 匹配 |
| rewrite / return | URL 重写 |
| try_files | SPA fallback |
| if + geo | 灰度发布 |
| add_header | CORS / 安全头 |
| limit_req | 限流 |
动手练习
- 实现 SPA History fallback
- 配置灰度发布(基于 IP / Cookie)
- 加安全头 + 限流
- 配置 WebSocket 反向代理
推荐阅读
下一章:第 211 章:Docker 入门与容器化 →