我们为 Web 服务器设置了故障转移设置,当出现某种硬件或连接故障时,我们会镜像实时 Web 服务器。目前,此过程要求我们更新 DNS,这显然取决于传播和缓存。如今的传播速度相当快,但缓存似乎变得越来越棘手。
我们并没有费心去采用更复杂的负载平衡解决方案,因为自从我们实施该设置以来,近五年来,没有任何理由需要意外地从实时切换到故障转移。实时服务器硬件规格高且坚固耐用,使用 RAID 进行存储,并且与大型柴油发电机和多个大型互联网管道共置在一个大型数据中心。即使去年我们遭遇的大规模全州停电也没有影响我们的服务器和网站。
但我们确实使用故障转移功能来应对计划中断 - 例如每 6 个月进行一次网站更新。我们在 DNS 中进行切换,然后必须等待实时服务器上的流量停止,这样我们在更新时就不会对用户造成太大的干扰。
那么,Apache HTTPD(某种 HTTP 标头)有没有办法告诉用户的浏览器他们应该刷新我们域的 DNS 缓存?
答案1
您的问题在于,您错误地假设客户端浏览器与 DNS 解析有关。在几乎所有情况下,它们都无关。它们让底层操作系统的 DNS 解析器处理名称解析和缓存机制。
如果您的故障转移策略与 DNS 记录更改相关,那么加快客户端周转的唯一选择就是降低生存时间所讨论记录的值。TTL 决定了客户端缓存该记录查找结果的时间。注意:也可以降低整个 DNS 区域的 TTL。但这可能不是您想要或需要的。
迁移到更传统的负载均衡器可以通过在真实服务器的 IP 前面放置虚拟/浮动 IP 地址来解决您的问题,这样您就不必进行任何 DNS 更改,并且您的故障转移可以或多或少是即时的。
答案2
我认为要求人们清除 DNS 缓存是不切实际的。大多数普通人不知道 DNS 是什么,不知道缓存是什么,即使你提供电话技术支持,他们也无法清除 DNS 缓存。想想必须清除路由器中的 DNS 缓存 - 路由器有数百种型号。如果你的客户都是技术高超的人,也许这更切合实际,但对于消费者来说,就不行了。
我认为你需要一个你可以控制的技术解决方案。
您可能最好使用为此设计的 DNS 服务,例如 AWS Route 53。R53 可以与任何地方的任何服务器一起使用,而不仅仅是 AWS 服务器/服务。R53 的工作方式有点像负载均衡器,有多个路由类型- 故障转移、加权、延迟等。您可以使用故障转移路由因此,如果主服务器出现故障,它会自动路由到备份服务器。
另一个选择是使用多个 A 记录,我确信这个选择不会奏效。这里的问题是浏览器将使用哪条记录?从我读过的内容来看,我的印象是浏览器应该随机使用 A 记录,但事实并非如此,它们使用第一个记录 - 虽然我不知道“第一个”是如何定义的。使用 DNS 分配负载的服务往往会随机化返回的 IP 地址的顺序。
评论中提到的另一个选项是反向代理。我最初没有包括这个,因为这意味着需要更多硬件。如果您在服务器/服务前面放置反向代理或负载平衡器,它可以将流量重定向到需要去的地方。我上面建议使用 Route53 可以执行类似的功能,效果不是很好,但可能比标准 DNS 好一点。
可以使用 302 临时重定向,但您需要一台能够在主服务器停机时持续发送这些重定向的服务器。这需要额外的硬件,但不需要太多硬件。
答案3
Apache HTTPD(某种 HTTP 标头)是否有办法告诉用户的浏览器应该刷新其 DNS 缓存。
不存在这样的机制,所有现代网络浏览器及其执行的代码都在沙箱中运行,因此它们无法更改操作系统设置。
答案4
本地 DNS 缓存不受用户浏览器管理。它由操作系统级别管理。更改本地 DNS 缓存是管理员操作。出于安全原因,浏览器不设计为在其主机上执行管理功能。
您需要的是服务器端解决方案。此类问题的常见解决方案是使用反向代理例如nginx, 或者阿帕奇。
为了以允许主服务器和备份服务器停机的方式实现这一点,您可以在具有一个或多个专用 IP 地址的虚拟机中运行反向代理。这样,您(或您的云提供商)只需维护虚拟机;支持它的硬件可能会波动。
您的设置将是:
- 面向公众的 VM:www.yourdomain.com
- 后端主服务器:<主服务器的 ip 地址>
- 后端备份服务器:<备份的 ip 地址>
- 您网站的 DNS 指向 VM www.yourdomain.com
如果您使用 nginx,则要代理的公共网站将作为文件定义存储在 sites-available 目录中,并通过将它们符号链接到 sites-enabled 目录来激活。您可以为每个后端服务器设置一个站点定义,并通过更改符号链接来切换它们,或者您可以为每个后端计算机设置一个带有 proxy_pass 指令的站点定义,但其中一个指令被注释掉。
无论您如何设置,要切换后端,您只需更改站点文件,然后告诉 nginx 重新加载其配置:service nginx reload
。
下面是一个示例站点文件,其中每个后端都有一个 proxy_pass 指令,并且其中一个被注释掉:
server {
listen 80;
listen [::]:80;
server_name yourdomain.com www.yourdomain.com;
location / {
proxy_pass http://<ip address of main>:80;
# proxy_pass http://<ip address of backup>:80;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
您可以做更多的事情,包括在反向代理上缓存静态内容,但是这些应该可以帮助您入门了。