目前我们有些前端应用是部署在 jdos 上,并且通过 jdos 中的 nginx 来代理访问后端接口,后端通常会提供一个域名,默认情况下 nginx 通常是在启动时对域名进行 DNS 解析并且将解析结果缓存,之后便不再更新。
问题
但这样会导致一个问题:如果后端新增/下线某些机器,那么前端的 nginx 在没有重启的情况下无法感知到,仍然会把用户的请求代理到缓存的 IP 中,导致请求失败或者后端新增机器无法承接流量。
解决方案
这种情况下,只能重启前端应用的 nginx 才能解决。但这只能在后端提前通知我们,或者是在出了问题后,用户反馈或者通过监控告警才能发现,不能解决根本问题。所以需要有更好的解决办法。
方案1:直接跨域请求后端接口
最简单直接的方式就是在设计之初就不要通过前端应用去代理后端接口,而是让后端提供一个支持跨域访问的域名,前端直接请求这个域名。这适合新的应用,老的应用需要后端配合修改,可能会比较麻烦也有一定的风险。
方案2:开启 nginx 的动态解析能力
老的应用或者某些场景下必须要使用前端 nginx 来代理后端接口的情况下,可以通过开启 nginx 的动态解析能力,让 nginx 主动感知后端域名的 DNS 解析变更并将用户请求转发到正确的后端应用上。开启方法有以下几个步骤:
步骤1:设置 DNS 解析策略
解析时机
- 启动时解析:Nginx 启动时解析域名,缓存 IP 地址
- 运行时解析:根据配置定期重新解析
DNS 缓存
Nginx 会缓存 DNS 解析结果,可以通过以下指令控制:
valid:设置 DNS 解析结果的缓存有效时间,过期后重新解析resolver_timeout:定义 Nginx 等待 DNS 服务器响应的最大时间,超时将认为解析失败
nginx 配置示例:
1 | |
此设置可以放在 http/server/location 这几个指令内,可根据需要放置。比如你有多个 server 要共享此设置,就可以放在 http 下面。
步骤2:开启动态 DNS 解析
仅仅设置 resolver 指令并不能实现动态 DNS 解析,必须使用变量域名才能触发 Nginx 的运行时 DNS 解析机制。
nginx 配置示例:
1 | |
