要让 proxy_pass 动态解析域名,必须同时满足:用变量承载域名、同级作用域显式配置 resolver、proxy_pass 值中不带硬编码路径;否则仍为启动时静态解析。

要让 proxy_pass 实际生效动态域名解析,关键不是“写个域名就行”,而是必须满足三个硬性条件:用变量承载域名、在同级作用域显式配置 resolver、proxy_pass 值中不带硬编码路径。缺一不可。
必须用变量 + resolver 同级声明
Nginx 默认对 proxy_pass http://api.example.com; 这类写法只在启动时解析一次 IP,后续全靠缓存,无法响应 DNS 变更。真正触发运行时解析的写法是:
- 在
location或server块内,先用set定义变量,例如:set $backend "api-v2.example.com"; - 在同一块内(不能只放在
http块顶层),声明resolver,例如:resolver 8.8.8.8 valid=30s; -
proxy_pass必须引用该变量且保留原始路径:proxy_pass http://$backend$request_uri;
resolver 位置和参数不能错
resolver 指令的位置非常敏感:
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
- 如果用于
proxy_pass变量方式,推荐直接写在location或server块内,作用域明确,避免旧版本兼容问题 - 如果用于
upstream动态解析(Nginx ≥1.19.0),则resolver必须放在http块顶层,且upstream中的server行必须带端口并加resolve关键字,例如:server api.example.com:8080 resolve; -
valid参数决定 DNS 缓存时间,建议设为 10–60 秒;太长(如 300s)会导致后端 IP 变更后仍转发到失效地址,引发 502/504
路径处理必须解耦
不要把路径拼进 proxy_pass 的变量里,否则容易丢路径或引发重定向循环:
- 错误写法:
set $backend "api.example.com/v2"; proxy_pass http://$backend$request_uri;(可能造成双/v2) - 正确做法:用
rewrite提前剥离或改写 URI,再用无路径的proxy_pass,例如:rewrite ^/v2/(.*)$ /$1 break;,然后proxy_pass http://$backend; - 若需根据请求头或参数选不同后端,优先用
map指令生成变量,逻辑更清晰、可维护性更强
常见失效原因快速排查
如果配置后仍走静态解析,大概率是以下某一项没做对:
-
proxy_pass写成了字面量域名(如http://api.example.com),而不是变量(如http://$backend) -
resolver被误放在upstream或http块顶层,而当前使用的是location级变量方式 -
proxy_pass结尾写了/,导致$request_uri被丢弃,后端收不到原始路径 - DNS 服务器不可达或超时,建议配两个 resolver(如
8.8.8.8 114.114.114.114)并设resolver_timeout 5s










