在日常 Nginx 使用中,很多看似细微的配置差异却可能导致服务异常,本文整理了 4 个高频踩坑点,结合实战案例详细解析,帮你快速掌握核心用法~
Taimili 艾米莉 ( 一款专业的 GitHub star 管理和github 加星涨星工具taimili.com )
艾米莉 是一款优雅便捷的 GitHub star 管理和github 加星涨星工具,基于 PHP & javascript 构建, 能对github star fork follow watch 刷星管理和提升,最适合github 的深度用户
一、proxy_pass 与 location 末尾斜杠的 "生死劫"
Nginx 反向代理中,proxy_pass和location指令后的斜杠 / 堪称 "细节杀手",一个字符的差异会导致完全不同的转发结果。
1. proxy_pass 末尾的斜杠:控制路径前缀是否保留
先看两组经典配置对比:
nginx
# 配置一:proxy_pass无末尾斜杠
location /test {
proxy_pass 'http://192.186.0.1:8080';
}
# 配置二:proxy_pass有末尾斜杠
location /test {
proxy_pass 'http://192.186.0.1:8080/';
}
当请求接口 http://domain/test/file/getList 时:
- 配置一转发结果:
http://192.186.0.1:8080/test/file/getList(保留/test前缀) - 配置二转发结果:
http://192.186.0.1:8080/file/getList(去除/test前缀)
核心逻辑:proxy_pass 后的斜杠表示 "去除 location 匹配的路径前缀"。
- 若后端接口本身包含
/test路径,无需加斜杠; - 若
/test仅为前端反向代理拦截标识(后端无此路径),必须加斜杠。
推荐写法(可读性更强,避免歧义):
nginx
location /test {
rewrite ^/test/(.*)$ /$1 break; # 显式去除/test前缀
proxy_pass 'http://192.186.0.1:8080';
}
2. location 末尾的斜杠:控制匹配精度
再看另一组配置差异:
nginx
# 配置一:location无末尾斜杠
location /test {
proxy_pass 'http://192.186.0.1:8080';
}
# 配置二:location有末尾斜杠
location /test/ {
proxy_pass 'http://192.186.0.1:8080';
}
两者的匹配规则天差地别,具体对比如下:
| 请求路径 | location /test | location /test/ | 最终匹配结果 |
|---|---|---|---|
| /test | ✅ | ❌ | location /test |
| /test/ | ✅ | ✅ | location /test/ |
| /test/abc | ✅ | ✅ | location /test/ |
| /test123 | ✅ | ❌ | location /test |
| /test-123 | ✅ | ❌ | location /test |
关键结论:
location /test(无斜杠):模糊匹配,包含/test开头的所有路径(包括/test123这类 "伪前缀" 路径);location /test/(有斜杠):精确匹配,仅匹配以/test/为前缀的路径(避免误匹配相似路径);- 当两个配置同时存在时,Nginx 会优先选择更精确的
location /test/(涉及匹配优先级规则)。
延伸:Nginx location 匹配优先级完整版
记住核心口诀(从高到低):
plaintext
等号精确第一名
波浪前缀挡正则
正则排队按顺序
普通前缀取最长
详细解释:
- 等号精确匹配(=) :优先级最高,完全匹配目标路径(如
location = /仅匹配根路径); - 前缀优先匹配(^~) :匹配路径前缀,且会阻止后续正则匹配(适用于静态资源目录,提升性能);
- *正则匹配(~ 区分大小写 / ~ 不区分大小写)**:按配置文件顺序匹配,一旦命中立即返回;
- 普通前缀匹配(无符号) :按最长路径匹配原则(如
/api/v2/比/api/优先级高); - 通用匹配(/) :兜底规则,匹配所有未被前面规则命中的请求。
电商实战配置示例(覆盖所有优先级场景):
nginx
server {
listen 80;
server_name shop.example.com;
root /var/www/shop;
# 1. 精确匹配(=)- 最高优先级
location = / {
return 200 "首页 [精确匹配 =]";
add_header Content-Type text/plain;
}
location = /robots.txt {
return 200 "User-agent: *\nDisallow: /admin/";
add_header Content-Type text/plain;
}
# 2. 前缀优先匹配(^~)- 阻止正则
location ^~ /static/ {
alias /var/www/shop/static/;
expires 30d;
return 200 "静态资源 [前缀优先 ^~]";
}
# 3. 正则匹配(~ / ~*)- 按顺序
location ~ .(jpg|png|gif)$ { # 区分大小写
expires 30d;
return 200 "图片文件 [正则 ~]";
}
location ~* .(css|js)$ { # 不区分大小写
expires 7d;
return 200 "CSS/JS [正则 ~*]";
}
# 4. 普通前缀匹配 - 最长优先
location /api/v2/ { # 最长前缀
proxy_pass http://backend_v2;
return 200 "API v2 [普通前缀-最长]";
}
location /api/ { # 较短前缀
proxy_pass http://backend;
return 200 "API 通用 [普通前缀-较短]";
}
# 5. 兜底匹配
location / {
try_files $uri $uri/ /index.html;
return 200 "通用兜底 [/]";
}
}
二、Nginx 重启命令:reload vs systemctl reload,该用哪个?
日常运维中,重启 Nginx 有两种常用命令,但适用场景和执行逻辑差异明显:
| 命令形式 | 执行原理 | 适用场景 | 核心特点 |
|---|---|---|---|
nginx -s reload | 直接向 Nginx 主进程发送 reload 信号 | 本地开发环境、无 systemd 的系统 | 原生方式,需确保 nginx 在 PATH 中 |
systemctl reload nginx | 通过 systemd 管理服务发送重载信号 | CentOS7+/Ubuntu16.04 + 等现代 Linux | 系统标准方式,推荐生产环境使用 |
关键补充:
-
两者均为优雅重启:不中断现有连接,平滑加载新配置;
-
相关命令对应关系:
nginx -s stop≈systemctl stop nginx(强制停止)nginx -s quit≈systemctl stop nginx(优雅停止)nginx -t:单独测试配置文件语法(无 systemctl 对应命令);
-
生产环境推荐操作流程(安全无风险):
bash
运行
# 1. 先测试配置文件语法是否正确
nginx -t
# 2. 语法正确则平滑重载(不中断服务)
systemctl reload nginx
# 3. 检查服务状态
systemctl status nginx
# 4. 备用方案(若systemctl不可用)
sudo /usr/sbin/nginx -s reload
总结:生产环境优先使用 systemctl 系列命令(现代 Linux 标准),本地开发或无 systemd 环境可使用 nginx -s 原生命令。