通过负载均衡器+域名实现容灾切换-(8)基于DNS解析的GSLB在BS架构中应用实践(转)(2)
=================================================================================================
原文:Why DNS Based Global Server Load Balancing (GSLB) Doesn’t Work http://www.tenereillo.com/GSLBPageOfShame.htm
Why DNS Based GSLB Doesn't Work, Part II http://www.tenereillo.com/GSLBPageOfShameII.htm
=================================================================================================
An Axiom
对于GSLB,唯一能够实现高可用的方法就是在DNS解析结果中包含多个A记录。
高可用实现有超多的替代的解决方案,但是没有一个能够真正奏效(见下文“替代方案” ),除了修改所有可能访问该站点PC的注册表,在解析结果中回复多个A记录是唯一的方法。
为什么多重A记录会抵消GSLB的负载均衡算法?
就像前文提到的,DNS服务器能够在解析结果中返回多重A记录。GSLB设备同样也可以返回多重A记录。即使互联网站点已经拥有DNS服务器(或购买了DNS解析服务),互联网站点的拥有者仍会采购GSLB设备,通常每台高达$30000,为的是获得那些比普通DNS服务器能提供的更多的特性。
问题来了:
这些特性中,没有一个特性可以同多重A记录配合使用 。
简单的站点Active/Standby算法不行、静态的站点偏好算法不行、基于IANA的站点偏好算法不行、DNS persistence 算法不行,RTT或步长检测算法不行,基于Geotargeting的重定向也不行…没有任何一个特性可以!下图就来展示为什么:
基于GSLB的DNS解析前面已经阐述过了(为了简便,像健康检查、RTT测量等步骤这节就省略掉了)。
1)我们假设GSLB设备设置站点A为首选站点,IP地址1.1.1.1 ,它在解析响应中按照如下顺序返回解析结果:
- 1.1.1.1
- 2.2.2.2
2)客户端的Local DNS 收到解析结果后,将结果缓存。此时Local DNS将结果返回给客户端,顺序可能是:
- 1.1.1.1
- 2.2.2.2
或者:
- 2.2.2.2
- 1.1.1.1
目前,几乎所有的商用GSLB设备都会返回有顺序的多重A记录,通常被称为“顺序列表”。设想预定的结果顺序会一成不变穿越互联网传递给DNS请求者,不幸的是,这个设想是错误的。
实践证明:DNS解析结果的地址顺序会被客户端的Local DNS 篡改!
Local DNS服务器篡改解析结果中的地址顺序是为了平衡去不同站点的流量,这是大多数提供商DNS服务器的默认动作。曾经有想法是将DNS响应结果的TTL设置为0,来避免Local DNS篡改顺序。但是非常不幸,解析结果的顺序仍会被篡改,完全不受GSLB或权威名字解析服务器的控制,这种情况下,确定性的控制客户端优先访问某一站点是不可能的。
网站Cookies:猜怎么着?依然不能奏效!
大多数多地部署的网站都要求会话的持续。换句话说,如何一个客户端连接到了站点A,那么必须要保证在整个会话期间,客户端一直连接在站点A。即便是站点已经很好的同步以适应某种级别的会话持续,然后实时同步是不可能做到的。
浏览器DNS缓存是解决会话持续的一线希望。客户端解析了www.trapster.net 之后,得到结果是站点A---IP 1.1.1.1,客户端会持续连接到站点A直到浏览器缓存过期。前面提到过,IE的过期时间是30分钟,Netscape是15分钟。很明显,单独使用这个方法不能满足超过30分钟(或15分钟)的会话的持续性,因为超时后浏览器会重新解析域名,这时客户端可能会连接到错误的站点。同时,不论30分钟或15分钟,都是固定的时间段,不是客户端停止使用的等待时间。例如,一个用户访问了www.trapster.net,然后接了29分钟电话,挂断了电话后,继续浏览www.trapster.net 开始订购某些商品,浏览器会在一分钟后重新解析,很可能将用户引导到错误的站点。
DNS缓存时间超时问题是众所周知的,因此基本上所有的SLB(服务器负载均衡)都会去解决这一问题。使用一种被称为“站点 cookie”的方法,通常只为HTTP协议部署(也有一些厂商为流媒体协议实现了该方法)。
- 客户端解析www.trapster.net的结果——站点A、IP地址1.1.1.1。客户端连接到站点A,开始商务事务。在连接到站点A的同时,站点A的SLB设备植入了HTTP cookie,该cookie 指明了客户端需要持续连接哪个站点(甚至是具体的服务器)。
- 经过一段时间,客户端浏览器的DNS缓存过期后,客户端会重新解析,这次的解析结果是站点B、IP 地址2.2.2.2,该地址将会在客户端浏览器中缓存30分钟(或15分钟),客户端现在向站点B建立连接,当客户端连接到站点B,其发送的站点cookie 表明客户端的当前会话需要连接站点A。
- 站点B的SLB设备读取这个cookie后,发送了一个条HTTP重定向。HTTP重定向中的FQDN部分不能是www.trapster.net,因为该域名对应的解析结果2.2.2.2,仍然缓存在客户端的浏览器中。同时,也不能使用地址1.1.1.1重定向,因为如果不使用DNS域名做重定向,服务器软件和SSL认证通常不能正常的工作。因为这个原因,通常使用一个站点独立的FQDN。在这个例子中,HTTP重定向的域名可能是www-a.trapster.net(或 site-a.www.trapster.net)。
- 客户端现在用www-a.trapster.net 重新连接原来的站点继续商务事务。
经过一段时间,尤其是站点经历了很长的会话时间(比如股票交易或财经站点),很大比例的用户会通过站点独立的FQDN连接到网站。即使经过短暂的会话时间,有些用户也会使用到站点独立的FQDN www-a.trapster.net。
因为有用户已经使用了www-a.trapster.net,为了高可靠性考虑,不仅仅需要为www.trapster.net使用多重A记录,而且还要为www-a.trapster.net使用多重A记录。如果IP 1.1.1.1 和 IP 2.2.2.2 都包含在www-a.trapster.net 的解析结果中,如前文所述,客户端可能会连接站点A,也可能是站点B!
站点cookie 不能很好的与多重A记录一起工作,同GSLB不能很好的与多重A记录一起工作的原因一样!
GSLB站点健康检查有用吗?
我们已经证明了多重A记录是有必要的,但是剩下的问题是“他们能胜任基于B/S架构的站点吗?”。
当收到包含多重A记录的解析结果后,基于浏览器的客户端使用它们自己的“健康检测”方法,这就是为什么多重A记录会设计在DNS协议中。也许有这样的情形,要求GSLB在解析结果中不返回已经检测到失效站点的A记录,但是也有很多情形要求返回失效站点的A记录,即使明确检测该站点失效。这一节就展示这样一个情形,许多种类的故障是很短暂的,换句话说,同样的问题可能会在不同站点间次序的或同时的出现。例如:
- 电力故障也许会影响一个区域的数据中心,并且当电缆网络调整期间,也许会影响其他地区的数据中心。
- 拒绝服务器攻击(DoS)通常攻击指定的IP地址。一次DoS攻击也许会先攻击IP地址1.1.1.1,然后再攻击IP地址2.2.2.2。
- 电脑病毒也许会先影响数据中心A,也许会花半小时来人工的杀除病毒,在这期间,该病毒也许会在数据中心B爆发。
- ISP内部网络出现问题,一个路由器问题会同时影响一个国家不同区域的网络。
根据前面的例子,站点A使用IP地址1.1.1.1,站点B使用IP地址2.2.2.2,如果一台SLB或GSLB设备(或者是绑定的某个健康检测脚本),发现站点A失效了,应该在解析结果中只返回单一的A记录2.2.2.2吗?如果站点B使用IP地址2.2.2.2随后也发生了故障,但是站点A在半小时的窗口中,从故障恢复,这种情况下最好还是一直返回两个站点的A记录,即使健康检测进程检测到了失败。记住,返回多重记录很少是适得其反的,因为客户端会自动地连接A记录列表中健康的站点,不需要人工干预。
替代方法
还有一种不太严重的故障会发生。一个站点的所有服务器故障,然而站点的电力、互联网连接和SLB设备都工作正常。此类问题有许多商业上可用的解决方案,包括backup redirection, triangulation,proxying,或NATing。为了完整性这里会讨论一下这些解决方案,但是这节会说明,这些解决方案虽然可以解决不太严重的服务器故障,但是并不能解决更重要的站点故障问题。
Triangulation
Triangulation 是一种连接恢复方法,对所有的IP 协议都适用。
- 客户端已经连接到站点A,正常的浏览网站。
- 站点A的所有服务器故障(但是在这个例子中,SLB、互联网连接、交换机、路由器、电力等设备都正常)。运行在站点A的SLB上的软件检测到了服务器故障,当然所有的存在的TCP连接都会丢失,但是客户端会尝试重连。在站点A的SLB与站点B事先有预建立的TCP隧道,站点A的SLB将客户端的新连接请求通过TCP隧道转发给站点B。
- 站点B的SLB设备选择一个新服务器为该客户端提供服务,并且使用冒名的地址1.1.1.1将数据包直接返回给客户端。
Backup redirection
Backup redirection 只对应用层支持重定向的协议有效(比如 HTTP、HTTPS、一些流媒体协议等)。
- 客户端向站点A发起请求,请求的URL是FQDN www.trapster.net,已经解析为IP地址1.1.1.1。
- 站点A的SLB发现所有的服务器都故障了,于是发出一个HTTP重定向引导用户去连接站点B。这里的重定向必须使用一个不同的FQDN,可以是www-b.trapster.net。如果HTTP重定向使用www.trapster.net,客户端的会使用已经缓存的地址(1.1.1.1)重新连回站点A。并且HTTP重定向可能不可以使用IP地址,因为大多数的服务器、SSL认证等,需要客户端通过FQDN访问站点,而不能是IP地址。
- 客户端现在访问站点B。
IP proxy 和 NAT
IP proxy(和NAT)对所有的IP协议都有效,这里不详细介绍他们了。这两个方法,在发现站点A的所有服务器故障后,会将客户端的连接负载均衡到站点B的VIP(2.2.2.2)上,就像将客户端连接负载均衡到本地服务器一样。
Triangulation、backup redirection、IP proxy和NAT的问题
这些方法确实会对站点故障快速恢复有所帮助,但只能是在互联网连接、网络设备、电力和本地SLB设备都工作正常的情况下起作用,换句话说,仅当服务器故障时有效。如果这些方法同多重A记录一同使用,这些方法的能否起作用是值得怀疑的。如果单独使用这些方法,而不使用多重A记录,等于是“丢了西瓜拣芝麻”。如果不将站点的灾难性故障考虑在内,那也没有什么强有力的论据去使用GSLB。看来最好是完全忘掉GSLB,丢弃那些花费和复杂性,将所有的服务器聚集在一个数据中心,而不是两个,使用冗余的电力、网络连接、网络设备、和SLB设备。
这就是说,即使在灾难情况下的高可用是对GSLB最基本的需求,GSLB也只能在特定情况下满足,因此:
对于高可用的需求,Triangulation、backup redirection、IP proxy和NAT,这些方法都不能满足,或者说不需要。基于浏览器的客户端仍需要使用多重A记录。
BGP主机路由注入
还有一个解决方案,通常被叫做BGP主机路由注入(HRI),同时,至少有两家厂商也叫做“Global IP”。他并不是简单与GSLB配合的备选方案,而是一种用来替换基于DNS的GSLB的解决方案。下面是其原理的概述:
- 客户端发起DNS解析,www.trapster.net 的解析结果中只有一个IP地址——1.1.1.1。
- 站点A和站点B的SLB设备(或路由器)都向互联网宣告了地址1.1.1.1。互联网路由器将1.1.1.1的路由信息通过BGP传播,同时交换度量值,最终将路由信息传播给距离客户端最近的互联网路由器,该路由器选择度量值最小的路径,将1.1.1.1的路由加入路由表。
- 客户端此时连接拓扑上最近的站点。
此时发生了服务器(全部)故障,或互联网连接故障、电力故障、SLB设备故障、网络设备故障等灾难性故障:
- 站点A的SLB设备发现了服务器故障,停止通过BGP向互联网宣告IP地址1.1.1.1(或 SLB、互连网连接被破坏,这种情况下宣告显然会停止)。
- 路由在互连网设备间收敛,前往站点A的路由条目最终会被删除。
- 客户端重新建立连接,仍连接IP 1.1.1.1,但这次连接的是站点B。
虽然在理论层次上,这个方案实现的功能像是GSLB梦寐以求的,但是它很少真正部署实现,下面阐述了为什么:
- 互联网的路由相当复杂,在不同地区宣告同一个IP地址的实践,工作的并不可靠。在客户端的会话期间,如果发生路由变动,数据包会在站点A和站点B之间断断续续的传输,此时,即使两个站点都可以正常工作,客户端依然不能正常访问。
- 路由收敛的时间会相当的长。当站点发生故障后,客户端的浏览器会超时,会跳转访问失败的页面。如果用户手动的持续尝试访问,最终连接会恢复,但是故障恢复时间超过5分钟也是有可能的,这么长时间的故障对于商业站点来说是不能接受的。
- BGP宣告的单个IP地址(主机地址)通常会被互联网路由器忽略。一个可能的解决方式是宣告整个网络地址段,然而仅仅为了GSLB这么做,等同于浪费昂贵的公网IP地址资源(因为仅仅一个地址,或一小部分地址会被实际使用到)。
- 为了安全考虑,路由器上会配置源地址过滤(有时叫做“bogon”过滤),源地址过滤会防止从不同的地域宣告同一IP地址。这个问题通常可以通过与ISP协商解决。尽管如此,即使与ISP协商去掉了源地址过滤,通常还会有人疏忽的重新加上去,这通常会造成站点失去互联网连接,需要故障报修处理等。
BGP HRI在站点分布在较小地域范围的网络中算是个健全的解决方案,也许可以用于一些互联网应用,但是部署相当的少见,因为它在实践中的表现远远不如理论分析的好。
结论
实现B/S架构的GSLB高可用,唯一的方法就是在解析响应中返回多重A记录,但是返回多重A记录,会破坏目前任何站点选择算法的作用。因为这些特性,比如基本的active-standby算法、DNS persistence算法、基于RTT或步长或BGP跳数的站点选择算法、基于IP地址geotargeting或基于IANA的站点选择都不能奏效。
好消息是,现在消费者可以将原本花GSLB上的每单元$30000,用在购置更多的服务器和提升站点内部同步能力上!
Watering it down
冒着混淆前文理论的风险6,写了下文:
至少在理论上,GSLB设备可以以某种 “最佳选择+轮询” 的模式运转,例如如果一个FQDN在欧洲有两个站点,在美国有两个站点,对于欧洲的客户端,为了更好的服务,GSLB只返回位于欧洲的两个站点的A记录给客户端的Local DNS服务器。客户端的Local DNS服务器会在两个站点间轮询负载。见下图:
- 在这之前(没有在图上显示),客户端请求解析FQDN www.trapster.net,最终解析请求迭代到了www.trapster.net的权威服务器,也就是GSLB设备。GSLB执行站点选择算法,为客户选择法兰克福和巴黎站点,排除洛杉矶和纽约。
- GSLB返回两个站点的IP 1.1.1.1 和2.2.2.2。
- 解析结果中的A记录顺序会被客户端Local DNS服务器打乱,但是在这个例子中,该行为是可接受的,客户端会连接法兰克福或巴黎站点。
为了更好的说明,我随便选择一个术语“区域”,来描述这个GSLB拓扑结构。
上文提到的站点A和站点B被划分为“欧洲GSLB区域”,站点C和站点D划在“美国区域”。这个方法,只有在网站的站点分布在全球,且划分为不同的区域,每个区域至少包含两个数据中心互为备份,这种情况下,才能被全局负载均衡。如果www.trapster.net的数据中心分布在伦敦、纽约、东京,那么“最佳选择+轮询”的模式就不会奏效了。某一客户端在伦敦,GSLB需要返回伦敦站点的A记录(地理位置最近的站点),同时它必须至少返回另一个站点的IP(纽约或东京,两个站点与伦敦的距离都不近)。客户端会连接伦敦的站点或者连接其他的站点。很明显,这明显违背了GSLB站点选择算法的初衷。同时,一些站点选择算法(例如步长计算)不能在“最佳选择+轮询”模式下工作(留给读者来思考),DNS persistence 算法也不能同“最佳选择+轮询”协同。即使这个复杂的实现可以为超大的全球站点服务,对于本文讨论的案例来说该方法并不是一个通用的解决方案。
=================================================================================================
对于基于浏览器的客户端来说,如果与返回多个A记录的惯常做法结合起来,基于全局服务器负载均衡 (GSLB)的DNS无法正常生效。Part 2 在忽略多A记录的高可用性因素情况下,涵盖了一些与基于GSLB的DNS的其他问题。
在GSLB的DNS工作原理Part 1已经描述,这里不再重复。
DNS解析时的就近路径问题:
问题一:客户端通常在地理上不接近器缓存DNS服务器。
基于GSLB的DNS解析过程中,没有任何一个GSLB设备能够确定实际客户端的IP地址和位置。因为和唯一和GSLB直接通信的设备是客户端的缓存DNS服务器。GSLB必须假定客户端在地里上接近其缓存DNS服务器,不幸的是,这个是不好的假定。
下图展示了两个客户端及其各自的缓存DNS服务器的地里关系:
- Author位于卡尔萨德,Author的客户端通常被分配到位于20英里外的一个主DNS服务器(缓存DNS服务器),位于圣迪伊戈,在美国圣迪亚哥。
- Author的家庭成员也生活在卡尔斯巴德,但使用的一个Service的所有主机的缓存DNS服务器位于亚特兰大,大约2000英里以外。