nginx upstream 块中无原生 resolve 参数,该写法会报错;真正动态解析需三要素协同:http 块中配置 resolver 及 valid、upstream 中 server 使用变量(如 $backend_host:8000)、proxy_pass 引用该 upstream,nginx 方可在请求时按缓存时效重新解析域名。

Nginx 的 upstream 块中并没有原生的 resolve 参数。这是常见误解——resolve 并非 upstream 指令的合法选项,直接写会触发配置错误(nginx: [emerg] unknown directive "resolve")。
真正支持动态 DNS 解析的机制:resolver + valid + 变量域名
要让 upstream 中的后端地址支持自动刷新 DNS(比如对接 Kubernetes Service、云厂商 SLB 或滚动更新的容器服务),必须结合以下三个要素:
-
在 http 或 server 块中显式声明
resolver:指定 DNS 服务器地址(如resolver 10.10.10.10 valid=30s;),valid控制缓存时间; -
upstream 中使用变量(而非字面量)作为服务器地址:例如
server $backend_host:8080;; -
通过 proxy_pass 引用该变量,并确保变量值来自请求上下文或 map 模块映射:Nginx 在每次请求时解析变量中的域名,若启用了
resolver且 DNS 缓存过期,就会发起新查询。
典型可刷新 upstream 配置示例
以下是一个安全、可运行的动态解析模式:
http {
resolver 114.114.114.114 valid=10s;
map $host $backend_host {
default "api.example.com";
~^service-(\w+)\.local$ "$1-backend.svc.cluster.local";
}
upstream dynamic_backend {
server $backend_host:8000;
}
server {
location /api/ {
proxy_pass http://dynamic_backend;
proxy_set_header Host $backend_host;
}
}
}
注意:server $backend_host:8000 是关键——只要 $backend_host 是变量,Nginx 就会在每次请求时重新解析其值对应的域名(前提是已配 resolver)。
为什么不能直接写 server api.example.com:8000 resolve;?
旧版 Nginx(resolve 参数,但从未进入官方主线。当前稳定版(1.20+)完全不识别该关键字。强行添加会导致启动失败。官方推荐路径始终是 resolver + 变量 组合。
注意事项与常见坑
-
resolver必须写在http或server块顶层,不能放在upstream内; - 变量必须在
proxy_pass或fastcgi_pass等指令中被实际使用,Nginx 才会触发解析;仅在upstream中定义变量不会生效; - DNS 解析失败时,默认返回 502;可通过
proxy_next_upstream error timeout invalid_header http_502;配合健康检查降级; - 容器环境(如 Docker/K8s)中,
resolver应指向集群 DNS(如 CoreDNS 的 ClusterIP),避免用宿主机 DNS 导致解析异常。











