我们在http://sstatic.net的网站之间提供了一组共享的静态内容。不幸的是,这个内容目前根本没有负载平衡——它是从单个服务器提供的。如果该服务器有问题,所有依赖它的站点都会有效地关闭,因为共享资源是必不可少的共享 javascript 库和图像。
我们正在寻找方法来平衡此服务器上的静态内容,以避免单一服务器依赖。
我意识到循环 DNS 充其量只是一种低端(有些人甚至可能会说ghetto)解决方案,但我不禁想知道循环 DNS 是否是静态内容基本负载平衡的“足够好”的解决方案?
[dns] [load-balancing]标签中对此进行了一些讨论,并且我已经阅读了有关该主题的一些很棒的帖子。
我知道通过多个循环 A 记录进行 DNS 负载平衡的常见缺点:
- DNS 记录通常没有心跳或故障检测,因此如果轮换中的给定服务器出现故障,则必须手动从 DNS 条目中删除其 A 记录
- 生存时间 (TTL) 必须设置得非常低才能使其正常工作,因为 DNS 条目在整个 Internet 中被积极缓存
- 客户端计算机负责查看有多个 A 记录并选择正确的记录
但是,对于我们的静态内容,“在我们研究和实施更好的替代方案时”形式的负载平衡,轮询 DNS 作为一个初学者是否足够好,总比没有好?还是在任何情况下,DNS 循环法都毫无价值?
杰夫,我不同意,负载平衡并不意味着冗余,事实上恰恰相反。您拥有的服务器越多,您在给定时刻发生故障的可能性就越大。这就是为什么在做负载均衡时必须要有冗余,但不幸的是有很多解决方案只提供负载均衡而不执行任何健康检查,从而导致服务可靠性降低。
通过将负载分布在多个点(可能在地理上分布),DNS 循环非常适合增加容量。但它不提供故障转移。您必须首先描述您要涵盖的故障类型。必须使用标准 IP 地址接管机制(VRRP、CARP、...)在本地覆盖服务器故障。交换机故障由服务器上到两个交换机的弹性链路覆盖。WAN 链路故障可以通过您和您的提供商之间的多链路设置来解决,使用路由协议或第 2 层解决方案(例如:多链路 PPP)。站点故障应该由 BGP 覆盖:您的 IP 地址在多个站点上复制,并且您仅在它们可用的地方向网络公布它们。
从您的问题来看,您似乎只需要提供服务器故障转移解决方案,这是最简单的解决方案,因为它不涉及任何硬件,也不与任何 ISP 签约。为此,您只需在服务器上设置适当的软件,这是迄今为止最便宜和最可靠的解决方案。
您问“如果 haproxy 机器出现故障怎么办?”。一样的。我认识的所有使用 haproxy 进行负载平衡和高可用性的人都有两台机器,并在它们上运行 ucarp、keepalived 或 heartbeat,以确保其中一台始终可用。
希望这会有所帮助!
作为负载平衡,它是贫民区,但或多或少有效。如果您有一台服务器因负载而倒下,并希望将其分散到多台服务器上,那么这可能是这样做的一个很好的理由,至少是暂时的。
对于作为负载“平衡”的循环 DNS 有许多有效的批评,除了作为短期创可贴之外,我不建议这样做。
但是您说您的主要动机是避免单服务器依赖。如果没有某种自动化的方法来让死机停止轮换,作为一种防止停机的方法,它就不是很有价值。(通过将服务器从轮换中拉出的自动方式和较短的 TTL,它变成了贫民窟故障转移。手动,甚至不是那样。)
如果您的两台循环服务器中的一台出现故障,那么您 50% 的客户将出现故障。这比只有一台服务器的 100% 故障要好,但几乎任何其他进行真正故障转移的解决方案都会比这更好。
如果一台服务器发生故障的概率是 N,那么使用两台服务器的概率是 2N。如果没有自动、快速的故障转移,此方案会增加某些用户遇到故障的可能性。
如果您打算手动使死服务器停止轮换,您会受到执行速度和DNS TTL 的限制。如果服务器在凌晨 4 点死机怎么办?真正的故障转移最好的部分是整夜入睡。 您已经使用 HAProxy,因此您应该熟悉它。我强烈建议使用它,因为 HAProxy 正是为这种情况而设计的。
循环 DNS 并不是人们想象的那样。作为 DNS 服务器软件(即BIND)的作者,我们得到的用户想知道为什么他们的循环停止按计划工作。他们不明白,即使 TTL 为 0 秒,也会有一些缓存,因为无论如何一些缓存都会设置最短时间(通常是 30-300 秒)。
此外,虽然您的 AUTH 服务器可能会进行轮询,但不能保证您关心的那些 - 您的用户与之交谈的缓存 - 会。简而言之,轮询不保证从客户端的角度来看任何排序,只保证您的身份验证服务器提供给缓存的内容。
如果您想要真正的故障转移,DNS 只是一步。为两个不同的集群列出多个 IP 地址并不是一个坏主意,但我会在那里使用其他技术(例如简单的任播)来进行实际的负载平衡。我个人鄙视与 DNS 混在一起的硬件负载平衡硬件,因为它通常会出错。并且不要忘记 DNSSEC 即将到来,因此,如果您确实在该区域中选择了某些东西,请询问您的供应商在您签署您的区域时会发生什么。
我之前已经说过好几次了,我会再说一遍——如果弹性是问题,那么 DNS 技巧就不是答案。
最好的 HA 系统将允许您的客户对每个请求继续使用完全相同的 IP 地址。这是确保客户甚至不会注意到故障的唯一方法。
因此,基本规则是真正的弹性需要 IP路由级别的技巧。使用负载平衡器设备,或 OSPF“等价多路径”,甚至 VRRP。
另一方面,DNS 是一种寻址技术。它的存在只是为了从一个命名空间映射到另一个命名空间。它的设计不允许对该映射进行非常短期的动态更改,因此当您尝试进行此类更改时,许多客户端要么不会注意到它们,要么最多需要很长时间才能注意到它们。
我还要说,由于负载对您来说不是问题,您不妨让另一台服务器准备好作为热备用服务器运行。如果您使用愚蠢的循环,您必须在出现问题时主动更改您的 DNS 记录,因此您最好主动将热备用服务器投入运行,而不是更改您的 DNS。
我已经阅读了所有答案,但我没有看到的一件事是,如果服务器没有响应,大多数现代 Web 浏览器会尝试使用备用 IP 地址之一。如果我没记错的话,Chrome 甚至会尝试多个 IP 地址并继续使用首先响应的服务器。所以在我看来,DNS Round Robin 负载平衡总是比没有更好。
顺便说一句:我认为 DNS Round Robin 更像是简单的负载分配解决方案。
令人惊讶的是,有多少贡献者正在帮助贡献有关 DNS 轮询作为负载分散和弹性机制的虚假信息。它通常确实有效,但您确实需要了解它的工作原理,并避免所有这些虚假信息造成的错误。
1) 用于循环的 DNS 记录上的 TTL 应该很短 - 但不是零。将 TTL 设为零会破坏提供弹性的主要方式。
2) DNS RR 传播,但不平衡负载,它传播它是因为在一个庞大的客户群中,他们倾向于独立查询 DNS 服务器,因此最终得到不同的首选 DNS 条目。这些不同的第一选择意味着客户端由不同的服务器提供服务,并且负载分散。但这一切都取决于哪个设备正在执行 DNS 查询,以及它保存结果的时间。一个常见的例子是公司代理后面的所有客户端(为它们执行 DNS 查询)最终都将针对单个服务器。负载分散-但不均衡。
3) DNS RR 提供弹性,只要客户端软件正确实现它(并且 TTL 和用户注意力都不太短)。这是因为 DNS 轮询提供了服务器 IP 地址的有序列表,客户端软件应尝试依次联系每个地址,直到找到接受连接的服务器。
因此,如果第一选择服务器关闭,则客户端 TCP/IP 连接超时,并且如果 TTL 或注意力跨度都未过期,则客户端软件会尝试对列表中的第二个条目进行另一次连接 - 依此类推,直到TTL 过期,或者它到达列表的末尾(或者用户厌恶地放弃)。
一长串损坏的服务器(你的错)和大量的 TCP/IP 连接重试限制(客户端配置错误)可能会在客户端真正找到工作服务器之前很长一段时间。TTL 太短意味着它永远无法到达列表的末尾,而是发出一个新的 DNS 查询并获得一个新的列表(希望以不同的顺序)。
有时客户端不走运,新列表仍然以损坏的服务器开始。为了给系统提供客户弹性的最佳机会,您应该确保 TTL 比典型的注意力跨度更长,并且让客户到达列表的底部。
一旦客户端找到了一个工作服务器,它应该记住它,并且当它需要建立下一个连接时,它不应该重复搜索(除非 TTL 已过期)。较长的 TTL 可减少用户在客户端搜索工作服务器时遇到延迟的频率 - 提供更好的体验。
4) DNS TTL 自带,当您想要手动更改 DNS 记录(例如,删除长期损坏的服务器)时,短 TTL 允许该更改快速传播(一旦您有时间这样做),所以考虑在了解问题之前需要多长时间并进行手动更改之间的平衡 - 以及普通客户端只需在 TTL 到期时重新搜索工作服务器这一事实。
DNS round robin 有两个突出的特点,使其在广泛的场景中非常具有成本效益 - 首先它是免费的,其次它几乎与您的客户群一样在地理上分散。
它没有引入所有其他“聪明”系统所做的新“故障单元”。没有任何添加的组件会在整个负载的相互链接的元素上遇到共同的和同时的故障。
“聪明”的系统很棒,并引入了奇妙的机制来协调并提供无缝平衡和故障转移机制,但最终他们用来提供无缝体验的方法是他们的致命弱点——可能出错的额外复杂的事情,当它发生时,将提供整个系统的无缝故障体验。
所以,是的,DNS 轮询对于您迈出的第一步绝对“足够好”,而不仅仅是在一个地方托管所有静态内容的单个服务器。
我来晚了,所以我的答案可能只会徘徊在底部,被忽视,嗅嗅。
首先,问题的正确答案不是回答问题,而是说:
NLB 很成熟,非常适合这项任务,而且很容易设置。云解决方案有其自身的优缺点,这超出了这个问题的范围。
问题
例如,在 2 或 3 个静态 Web 服务器之间?是的,总比没有好,因为有DNS 提供商会将 DNS Round Robin 与服务器健康检查集成在一起,并将暂时从 DNS 记录中删除死服务器。因此,通过这种方式,您可以获得不错的负载分布和一些高可用性;这一切都需要不到 5 分钟的时间来设置。
但是其他人在此线程中概述的警告确实适用:
其他解决方案
HAProxy 很棒,但由于 Stack Overflow 位于 Microsoft 技术堆栈上,因此使用 Microsoft 负载平衡和高可用性工具可能会减少管理开销。网络负载平衡解决了一部分问题,微软现在实际上有一个L7 HTTP 反向代理/负载平衡器。
我自己从未使用过 ARR,但考虑到它是第二个主要版本,并且来自 Microsoft,我认为它已经过足够好的测试。它有易于理解的文档,这是一篇关于他们如何看待webnodes上静态和动态内容分布的文章,还有一篇关于如何使用ARR 和 NLB来实现负载分布和高可用性的文章。
我一直使用具有长 TTL 的 Round-Robin DNS 作为负载平衡器。它适用于带有浏览器的 HTTP/HTTPS 服务。
我真的对浏览器感到压力,因为大多数浏览器都实现了某种“在另一个 IP 上重试”,但我不知道其他库或软件将如何处理多 IP 解决方案。
当浏览器没有从一台服务器得到回复时,它会自动调用下一个 IP,然后坚持使用它(直到它关闭......然后尝试另一个)。
早在 2007 年,我就进行了以下测试:
http://roundrobin.test:10080/ping.php
我让它运行一个小时,有很多数据。结果是,对于套接字A上 99.5% 的命中,我在套接字B或C上都有命中(当然,我没有同时禁用这两个)。浏览器有:iPhone、Chrome、Opera、MSIE 6/7/8、黑莓、Firefox 3/3.5……所以即使是不兼容的浏览器也能正确处理它!
直到今天,我再也没有测试过它,但也许有一天我会设置一个新的测试,或者将代码发布到 github 上,以便其他人可以测试它。
重要提示:即使它大部分时间都在工作,但它并不能消除某些请求会失败的事实。我也将它用于 POST 请求,因为我的应用程序将在它不起作用的情况下返回错误消息,以便用户可以再次发送数据,并且在这种情况下浏览器很可能会使用另一个 IP 并且保存将起作用. 对于静态内容,它的效果非常好。
因此,如果您正在使用浏览器,请务必使用 Round-Robin DNS,无论是静态还是动态内容,您都会很好。服务器也可能在事务处理过程中宕机,即使使用最好的负载均衡器,您也无法处理这种情况。对于动态内容,您必须使会话/数据库/文件同步,否则您将无法处理此问题(但对于真正的负载均衡器也是如此)。
附加说明:您可以使用
iptables
. 例如,在您的 HTTP 流量防火墙规则之前,添加:iptables -A INPUT -p tcp --dport 80 --source 12.34.56.78 -j REJECT
(
12.34.56.78
显然你的IP在哪里)不要使用,因为它会过滤
DROP
端口,您的浏览器会等到超时。所以现在,您可以启用或禁用一台服务器或另一台服务器。最明显的测试是禁用服务器 A,加载页面,然后启用服务器 A 并禁用服务器 B。当您再次加载页面时,您会看到浏览器稍等片刻,然后它将从服务器加载又一个。在 Chrome 中,您可以通过查看网络面板中的请求来确认服务器的 IP。在 的选项卡中,您会看到一个名为. 这是您得到答案的 IP。General
Headers
Remote Address:
因此,如果您需要在一台服务器上进入维护模式,只需使用一条
iptables
REJECT
规则禁用 HTTP/HTTPS 流量,所有请求都会转到其他服务器(稍等片刻,用户几乎察觉不到)。Windows Vista 和 Windows 7在将 IPv6 地址选择反向移植到 IPv4 时以不同的方式实现客户端对轮询的支持。( RFC 3484 )
因此,如果您拥有大量 Vista、Windows 7 和 Windows 2008 用户,您可能会发现行为与您在 ersatz 负载平衡解决方案中的计划想法不一致。
如果您使用 RR DNS 进行负载平衡,那很好,但您不是。您正在使用它来启用冗余服务器,在这种情况下它并不好。
正如前一篇文章所说,您需要一些东西来检测心跳并停止打击它,直到它回来。
好消息是,无论是在交换机还是在 Windows 中,heartbeat 都非常便宜。
不知道其他操作系统,但我认为它也在那里。