nginx基于url路径分流有三种主流方式:1. 前缀匹配(location /path/),按最长前缀匹配并proxy_pass;2. 正则匹配(location ~ ^/json/(\d{4})/),配合if或rewrite动态分发;3. map映射(http块内定义变量),提升多规则场景的可维护性与性能。

在 Nginx 中实现基于 URL 路径的分流,核心是利用 location 指令匹配请求路径,并结合 proxy_pass 将流量定向到不同的 upstream 服务组。这种方式简单、高效、无需额外模块,适合网关层按业务域或接口前缀做路由分发。
用 location 匹配路径前缀做分流
这是最常用也最推荐的方式,适用于路径有明确层级结构的场景,比如 /api/、/admin/、/static/ 等。
- 每个
location块定义一个路径规则,Nginx 会按最长前缀匹配原则选择最精确的块 - 在对应块中使用
proxy_pass http://upstream_name指向预定义的服务集群 - 注意末尾斜杠一致性:若
location /api/,则proxy_pass http://api_backend/的结尾斜杠会影响重写行为
示例配置:
upstream api_backend { server 10.0.1.10:8000; }
upstream web_backend { server 10.0.1.20:3000; }
server {
listen 80;
location /api/ {
proxy_pass http://api_backend/;
}
location / {
proxy_pass http://web_backend/;
}
}
用正则匹配动态路径做分流
当需要根据路径中的变量(如 ID、区域码、版本号)做分发时,可用带 ~ 或 ~* 的正则 location,配合 等捕获组提取参数。
- 正则匹配优先级高于前缀匹配,但性能略低,建议只在必要时使用
- 避免在
location /内嵌套 if —— 官方不推荐,易出错且不可靠 - 可配合
rewrite提前标准化路径,再交由 location 处理
例如将 /json/0769/ 和 /json/0734/ 分流到不同后端:
upstream front_0769 { server 127.0.0.1:3333; }
upstream front_0734 { server 127.0.0.1:3334; }
location ~ ^/json/(\d{4})/ {
if ($1 = "0769") {
proxy_pass http://front_0769/;
break;
}
if ($1 = "0734") {
proxy_pass http://front_0734/;
break;
}
proxy_pass http://front_0769/;
}
用 map 指令做轻量级路径映射
当分流规则较多、逻辑较复杂(如按路径后缀、子域名、或 query 参数片段),推荐用 map 指令预先构建变量映射表,再在 location 中引用。它比多个 if 更清晰、更高效。
-
map必须定义在http块内,不能在 server 或 location 中 - 支持正则匹配、字符串匹配、默认值 fallback
- 变量名(如
$up_stream)可在后续proxy_pass中直接使用
示例:
map $request_uri $up_stream {
~^/json/0769/ front_0769;
~^/json/0734/ front_0734;
default front_0769;
}
upstream front_0769 { server 127.0.0.1:3333; }
upstream front_0734 { server 127.0.0.1:3334; }
server {
location /json/ {
proxy_pass http://$up_stream/;
}
}
注意事项与避坑点
实际部署中容易忽略几个关键细节:
-
proxy_pass后的 URI 若含路径(如http://s1/api/),会替换整个 location 匹配部分;若无路径(如http://s1),则原请求路径完整透传 - 启用
proxy_redirect可修正后端返回的跳转头,避免客户端重定向到内部地址 - 记得设置
proxy_set_header Host $host和X-Real-IP,确保后端能正确识别原始请求信息 - 不要在
if中直接写proxy_pass(除非加break),否则可能触发“invalid number of arguments”错误











