可通过location路径筛选将特定接口从轮询池剥离:优先用^~前缀匹配直连固定后端;复杂路径用~正则配合if判断请求方法;灰度场景可用upstream内hash实现定向;需注意proxy_pass斜杠一致性及location声明顺序。

直接在 upstream 外层用 location 做路径筛选,再把匹配到的请求单独 proxy_pass 到指定后端,就能把特定接口从轮询池中“剥离”出来——不走负载均衡,而是直连固定服务。
用正则 location 精准拦截目标接口
核心思路是:让需要剥离的接口,在进入通用 upstream 之前就被更优先的 location 拦截并处理。Nginx 的匹配优先级决定了这完全可行:
- = 精确匹配(最高优先级)
- ^~ 前缀最长匹配(非正则,但优先于普通正则)
- ~ 或 ~* 区分/不区分大小写的正则匹配(按配置顺序,首个命中即止)
- / 通用匹配(兜底,最低优先级)
例如,要把所有 /api/v2/payment/ 开头的请求固定转发到支付专用服务,不参与轮询:
location ^~ /api/v2/payment/ {
proxy_pass http://payment-backend:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}注意:^~ 比 ~ 和 / 优先,且不触发正则引擎,性能更好;末尾的 / 在 proxy_pass 中必须与后端路径对齐,避免 URI 重复拼接。
用区分大小写的正则匹配复杂路径模式
当接口路径含动态段、版本号或特殊标识时,正则更灵活。比如剥离所有带 v3 且以 /report 结尾的 POST 接口:
location ~ ^/api/v3/.+/report$ {
if ($request_method = POST) {
proxy_pass http://report-v3-service:9001;
break;
}
}说明:
-
~启用区分大小写正则,^和$锁定起止,避免误匹配 -
.+匹配中间任意非换行字符(如/user、/order/123) -
if内嵌判断请求方法,确保只剥离 POST 类型(GET 可继续走轮询) -
break阻止后续 location 匹配,防止被兜底规则覆盖
剥离后仍复用同一 upstream 组的技巧
如果只是想让某些请求“跳过轮询逻辑”,但后端仍是同一批机器(比如指定某台做灰度),可用 upstream 内部的 weight + ip_hash 或 hash 实现定向,而不用新建 location:
upstream backend_pool {
server 192.168.1.10:8080 weight=10;
server 192.168.1.11:8080 weight=1; # 低权重点,用于灰度
}
<p>location ~ ^/api/internal/ {
proxy_pass <a href="https://www.php.cn/link/b12eb2ad6b9e2f46db291c12271a942e">https://www.php.cn/link/b12eb2ad6b9e2f46db291c12271a942e</a>;
hash $uri consistent; # 同一 URI 总打到同一台,等效“剥离”
}</p>这种方式不新增配置块,适合灰度发布、AB 测试等场景,本质是用哈希代替轮询,而非绕过 upstream。
务必避开的两个典型坑
剥离失败往往不是正则写错,而是配置细节被忽略:
-
proxy_pass 尾部斜杠不一致:若
location /api/对应proxy_pass http://s1/,Nginx 会把/api/foo改写为/foo;若写成proxy_pass http://s1(无斜杠),则变成/api/foo—— 后端收不到预期路径 -
正则 location 位置放错:必须放在通用
location /之前,否则会被兜底规则先匹配,后续正则根本不会执行











