Nginx proxy_pass 动态解析DNS需用变量+同级resolver:变量值须含协议和结尾斜杠;resolver需与proxy_pass同作用域并设valid缓存时间;推荐map白名单防注入。

Nginx 负载均衡中,proxy_pass 本身不支持直接写死域名的动态更新——它默认在启动或重载时静态解析一次,后续全走缓存 IP。要实现「运行时按需查 DNS」的动态域名解析,关键不是“负载均衡算法”,而是让 proxy_pass 指向一个变量,并配合同级 resolver 指令触发实时 DNS 查询。
下面分三类实用场景说明配置要点,全部基于 Nginx 原生能力,无需 Lua 或第三方模块:
proxy_pass 变量必须含协议和结尾斜杠
proxy_pass 引用变量时,该变量值必须是完整、合法的 URI(即 http:// 或 https:// 开头,主机后必须带 /)。Nginx 不会自动补路径,缺斜杠会导致转发异常(如请求路径被截断)。
- ✅ 正确:
set $backend "https://api.example.com/";→proxy_pass $backend; - ❌ 错误:
set $backend "api.example.com";→proxy_pass http://$backend;(缺协议+路径,报错或 404)
建议统一在 set 或 map 中定义完整地址,避免拼接风险。
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
resolver 必须与 proxy_pass 同作用域且显式指定 DNS
resolver 不是全局开关,它只对同级或内层使用变量的 proxy_pass 生效。不能只在 http { } 顶层写,然后在 location 里用变量——旧版本(<1.19.10)根本不继承。
- 推荐写法:把
resolver放在location或server块内,紧邻proxy_pass使用处 - 示例:
location /api/ { resolver 114.114.114.114 valid=15s; set $backend "https://dynamic-service.internal/"; proxy_pass $backend; } -
valid=15s表示 DNS 缓存 15 秒,建议设为略小于后端 DNS 的 TTL(如后端 TTL 是 30s,这里设 25s),平衡及时性与查询压力。
动态来源推荐用 map 构造可信变量,而非 if/set 拼接
直接用 if 或 set 拼接用户输入(如 $arg_host)有注入风险(比如传入 evil.com; rm -rf /)。更安全的做法是用 map 预定义白名单映射:
http {
# 白名单映射:参数值 → 安全后端地址
map $arg_env $trusted_backend {
default "https://prod-api.internal/";
"staging" "https://staging-api.internal/";
"dev" "https://dev-api.internal/";
}
server {
location /api/ {
resolver 114.114.114.114 valid=20s;
proxy_pass $trusted_backend;
}
}
}这样既支持按请求参数切换后端,又杜绝了非法域名注入,变量值全程可控。
不复杂但容易忽略

















