NGINX如何根据query参数将请求路由到不同后端代理服务
NGINX 根据查询参数路由到不同后端的实现方案
核心用到NGINX内置的$arg_<参数名>变量直接获取查询参数值,配合map指令做路由映射,性能远高于多个if判断,是官方推荐的最佳实践。
完整配置示例
# map块必须定义在http块层级,不能放到server或location块内 http { # 定义route参数值与后端上游的映射关系 map $arg_route $proxy_backend { # 未匹配到规则时的默认上游,也可以留空后续做非法请求拦截 default http://default.cdn-origin.com; aws1 http://edge1.amazonwebservices.com; aws2 http://edge2.amazonwebservices.com; # 新增路由直接在下方加对应映射即可 # aws3 http://edge3.amazonwebservices.com; } server { listen 443 ssl; server_name edge1.cdn.com; # SSL证书配置请根据实际情况补充 # ssl_certificate /path/to/ssl.crt; # ssl_certificate_key /path/to/ssl.key; location / { # 拦截非法/缺失route参数的请求,不需要可以删除 if ($proxy_backend = "") { return 400 "Invalid or missing route parameter"; } # 代理到映射后的后端,$request_uri包含原始路径和所有查询参数 proxy_pass $proxy_backend$request_uri; # 标准代理请求头配置,可按需调整 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; # --- 可选配置:转发前移除route参数,后端不需要该参数时启用 --- # set $final_uri $request_uri; # # 移除URI中的route参数 # if ($final_uri ~ "^([^\?]*)\?(.*)route=[^&]*(.*)$") { # set $final_uri $1?$2$3; # } # # 清理参数移除后可能残留的多余&或?符号 # if ($final_uri ~ "^([^\?]*)\?(&|$)(.*)$") { # set $final_uri $1?$3; # } # 启用移除参数时,替换上面的proxy_pass为下面这行 # proxy_pass $proxy_backend$final_uri; } } }
配置说明
- 映射规则默认大小写敏感,如果需要不区分大小写匹配route参数,可以在匹配规则前加
~*前缀,例如:~*^aws1$ http://edge1.amazonwebservices.com; - 路由映射规则较多时,可以将所有映射行单独存入外部文件,在map块内用
include /path/to/route_maps.conf;引入即可,方便单独维护。 - 当
proxy_pass指令后携带变量时,NGINX不会自动处理URI的拼接,直接使用$request_uri可以保证原始请求的路径、其他查询参数(比如示例中的secure_link、tokens)完整传递到后端。
内容的提问来源于stack exchange,提问作者Mario Bernheim
相关产品推荐
相关产品推荐

