第五章 广域网服务器负载均衡

本章介绍广域网服务器负载均衡(Global Server Load Balancing,以下简称GSLB)的概念以及它产生的驱动力。我们将从DNS的基本概念开始,来理解GSLB的工作原理。然后,我们讨论实现GSLB的几种方法,包括基于DNS和非基于DNS的架构。最后,我们会介绍GSLB的一些应用及实现方法。
GSLB的功能可以嵌入到负载均衡产品中,也可以打包成一个独立的产品。象Foundry、Nortel、Cisco、Radware等厂商都是把GSLB集成到它们的负载均衡产品中。有些厂商把GSLB的功能从服务器负载均衡中分离出来做成独立的产品,例如F5 Networks。
5.1 GSLB的必要性
两个主要因素推动了GSLB产生:高可用性和更快的响应时间。
采用负载均衡器对服务器做健康检查,一旦有服务器发生故障,负载均衡器就透明的将流量引导到其他服务器,通过这种方法实现服务器群的高可用性。使用两台负载均衡器一起工作,就可以实现当一台负载均衡器故障,另一台来接管工作,通过这种设计实现了负载均衡器的高可用性。但是如果服务器群以及负载均衡器所在的数据中心断电呢?如果由于互联网服务提供商的故障造成我们的Internet连接中断呢?又如果由于天灾人祸,比如洪水或者地震造成Web站点所在的数据中心瘫痪?在一个数据中心之内,不管我们怎样考虑Web站点的高可用性,总还是有一些宏观因素会导致站点瘫痪。而使用GSLB,Web站点或其他应用服务器集群就可以分散放在多个数据中心里,当一个站点发生故障或者某个数据中心瘫痪时,可以将用户引导到其他正常工作的站点或数据中心。
负载均衡器在多个服务器之间分配流量,从而帮助我们提高系统的扩展性。我们可以使用更多更强大的服务器,部署多台负载均衡器,或者调整负载均衡算法尽可能得到最好的响应时间。到目前为止,我们无法控制的一个因素就是互联网延迟,如图5.1所示。用户的响应时间包括客户端延迟,互联网延迟和服务器端延迟。到目前为止,我们讨论过通过减少服务器端延迟的办法,从而改善用户响应时间。我们无法控制客户端延迟,那取决于客户端“最后一英里”的接入方式以及客户端电脑的性能。而互联网延迟是影响用户响应时间的一个重要因素。使用GSLB,Web站点或应用服务器就可以分散在多个数据中心,并且可以将用户导向到响应最快的站点,如图5.2所示。我们将会探讨通过哪些策略来确定最佳的站点。
图5.1 互联网延时是响应时间的一部分
图5.2 GSLB概况
GSLB可以通过多种方式实现,最常用的方法是DNS。了解DNS的基本知识是理解GSLB的基础,我们简要讨论一下DNS。
5.2 DNS概述
在需要访问Web站点foo.com时,我们在浏览器里输入URL,HTTP://www.foo.com/。浏览器必须首先找到HTTP://www.foo.com/对应的IP地址, DNS就从这时开始工作。
5.2.1 DNS概念和术语
地址HTTP://www.foo.com/是一个域名,而foo.com是一个域。互联网域名的结构就象一棵倒置的树,如图5.3所示。有一些域如com、gov和edu,都是顶级域。每个域都包含其他域,或者称作子域。Foo.com是域com的子域。Foo.com也可包含其他子域,比如a.foo.com或b.foo.com。ftp.a.foo.com是a.foo.com的一个子域。这些子域都可以说是域foo.com下的区域( Zone)。
图5.3 DNS的树形结构
域名服务器保存一个域名空间的所有信息,并且响应有关此域名空间的所有请求。域名服务器是一个给定域的的权威DNS服务器,它拥有这个域所有的域名信息。每个域都可以分为多个区域,而每个权威域名服务器可以给一个或多个区域解析。例如,foo.com有三个部门-a、b和c,我们可以把域foo.com划分为三个区域:a.foo.com、b.foo.com和c.foo.com。每个部门都可以为自己的区域维护自己的权威域名服务器。权威域名服务器也就是我们熟知的ZOA ( Zone of Authority )。DNS的详细标准请参考RFC 1034和RFC 1035。
一个域可以有多台权威域名服务器,但是只有一台是主域名服务器,这台主域名服务器负责向其他辅域名服务器分发每个域名空间的更新信息。我们采用多台权威域名服务器的方式,通过在多台域名服务器之间分发负载来提高整体的高可用性和扩展性。
本地域名服务器,也称作本地DNS服务器,是用户LAN中的域名服务器。当客户端在浏览器里请求URL:HTTP://www.foo.com/时,浏览器会向本地DNS服务器请求将HTTP://www.foo.com/解析成IP地址,如图5.4所示。那客户端如何找到本地DNS服务器的IP地址呢?本地DNS服务器地址是客户端网络配置的一部分,或者通过DHCP方式分配给客户端。DHCP是一种协议,在很多网络里用来自动的给客户端分配网络配置。DHCP可以分配的信息包括IP地址,子网掩码,缺省网关和可选的本地DNS。
图5.4 DNS解析流程图
当客户端向本地DNS服务器发起请求时,本地DNS服务器将域名解析成一个IP地址,解析过程如图5.4所示。本地DNS服务器首先会去根域名服务器请求解析,根域名服务器会返回.com域的域名服务器列表。本地DNS服务器在.com域名服务器列表中随机选择一个,发送域名解析请求,.com域的域名服务器将foo.com域的权威DNS服务器IP地址返回给本地DNS服务器。本地DNS向foo.com域的权威DNS服务器发送解析请求,最后foo.com域的权威DNS服务器将站点HTTP://www.foo.com/的web服务器的IP地址返回给本地DNS服务器。
如果有多台web服务器同时为站点HTTP://www.foo.com/提供服务,foo.com的权威服务器可能会解析出一个或多个IP地址。权威域名服务器还可以调整响应中IP地址的排列方式,即在每次响应中将不同的IP地址置于首位,轮循返回不同的IP地址。
通常DNS协议的端口是UDP53端口,DNS请求和响应数据包都是一个UDP包。一个UDP包最大是500个字节。这对DNS查询请求来说不是一个问题,但是如果DNS响应里包含很长的IP地址列表,数据包很可能超过500个字节的限制。权威DNS服务器会尽可能使用500个字节,并且在响应里设置一个标记,告诉本地DNS服务器再通过TCP的方式发送一个同样的请求。以TCP的方式再发送一次同样的请求,本地DNS可以获得完整的响应。
5.2.2 本地DNS缓存
一旦接收到响应,本地DNS服务器就会将这个信息保存一段时间,即常说的生存时间(TTL)。权威DNS服务器在返回DNS查询记录时指定TTL。也就是说,本地DNS服务器会用以前获取的记录来响应所有后续的请求,直到TTL过期。一旦TTL过期,下一个请求会触发本地DNS服务器向权威DNS服务器重新发起请求。在客户端发出相同域名解析请求时,本地DNS缓存能保证更快的响应时间。同时,TTL能保证本地DNS服务器能获知权威服务器的任何更新。调低TTL值会导致本地DNS服务器更频繁的去请求权威DNS服务器。而调高TTL值会使本地DNS服务器的更新时间变长,所以有信息过期的风险。
如果本地DNS服务器接收到多个IP地址的DNS响应,它会以轮询的方式每次返回给客户端一个IP地址。
除了DNS服务器能缓存DNS响应之外,客户端浏览器也可以缓存DNS响应。然而,目前流行的客户端浏览器会忽略由权威DNS服务器设置的TTL值,比如说微软3.x版本的IE会将DNS响应缓存24小时。除非把浏览器关掉或者重启,否则对一个给定的域名,3.x版本的IE浏览器在24小时内都不会向DNS服务器发出解析请求,IE 4.x及以后版本的缓存时间是30分钟。微软的支持网站提供了通过修改注册表来改变IE浏览器中默认DNS缓存时间的方法。(在微软网站的支持版块搜索关键字”ie cache dns timeout”)。
5.2.3 使用标准DNS实现负载均衡
通过标准的轮循机制,DNS可以在多台服务器之间实现负载均衡。域名对应的每一个IP地址就是负载均衡器上的VIP,VIP与连接在负载均衡器上的服务器绑定。DNS可以用来实现多台服务器之间的负载均衡,也可以实现不同站点的负载均衡,每个站点之内通过负载均衡器实现服务器的负载均衡。
但是DNS不知道哪一个IP地址能正常工作,也不知道每个站点的负载状况。一个站点可能根本无法访问,但是DNS会继续将它的IP地址作为解析结果返回给客户端。这并不是DNS架构的缺陷,DNS在设计之初就不是用来实现GSLB的,它只是域名和IP地址之间转换的一种方法。
5.3 HTTP 重定向
使用HTTP重定向的方法可以不改变DNS系统的配置也能提供GSLB服务。在HTTP协议的定义里包含一个方法重定向, Web服务器在向客户端回复的HTTP响应里包含一个重定向代码和一个重定向URL。这是通知客户端浏览器,为了获取请求的内容,必须去重定向的URL。图5.5显示了HTTP重定向的工作过程,当用户输入HTTP://www.foo.com/时,本地DNS服务器将域名HTTP://www.foo.com/解析成位于纽约的数据中心的Web服务器的IP地址。当客户端浏览器发起HTTP请求时,纽约数据中心的Web服务器将浏览器重定向到HTTP://www1.foo.com/。于是浏览器将又一次去本地DNS服务器,将域名HTTP://www1.foo.com/解析成位于圣何塞的数据中心的Web服务器的IP地址。最后,浏览器向圣何塞数据中心的Web服务器发起HTTP请求,获得Web页面的内容。纽约数据中心的Web服务器可以根据不同的参数和策略来决定是否重定向一个用户的访问以及重定向到何处。
图5.5 HTTP重定向
我们来看看HTTP重定向的优势。首先,对已有的DNS系统及配置不需要做改变。其次,当纽约数据中心的服务器接收到HTTP请求时,它知道客户端的IP地址,这非常关键,我们在接下来的部分,站点选择策略,将会详细讨论。当然HTTP重定向也有其不足。顾名思义,这种方法只适用于HTTP应用,不适用于任何其他应用。其次,由于HTTP重定向过程需要额外解析域名www1.foo.com,还需要与www1.foo.com建立TCP连接并且发送HTTP请求,响应时间就会加长。第三,由于所有用户必须首先访问HTTP://www.foo.com,这将会成为性能和可靠性的瓶颈,尽管这个瓶颈可以用标准DNS轮循的方法来解决。
5.4 基于DNS的GSLB
基于DNS的GSLB实际上就是在DNS架构里实现GSLB。我们需要把负载均衡器部署在DNS架构里,并且选择最好的站点的IP为客户端提供服务。为了理解基于DNS的GSLB,我们需要将它分成两个步骤来阐述。首先,如何将负载均衡器部署在DNS架构里,以便它能将一个最好的站点的IP地址响应给一个给定的用户;其次是负载均衡器如何选择最好的站点是。
5.4.1在DNS架构里部署负载均衡器
我们将讨论几种方法把负载均衡器部署在DNS架构里来实现GSLB,这几种方法的区别在于,负载均衡器实现的DNS功能的多少以及它们对已有的DNS系统配置的影响。
负载均衡器作为权威DNS服务器
最简单的的做法是把负载均衡器作为一个特定的区域或者一个域名空间的权威DNS服务器,如图5.6所示。权威DNS服务器的地址注册成负载均衡器上的VIP,这样负载均衡器就会接收所有的DNS请求,提供对域名的智能DNS解析,而这是普通的DNS不能做的。市场上大多数的GSLB产品都可以实现这个功能。
图5.6 负载均衡器作为权威DNS服务器
由于负载均衡器已代替现有的DNS服务器,接管了权威DNS服务器的解析工作,网络或多或少都会受到影响,影响的程度取决于负载均衡器能实现的DNS功能的多少,这因产品而异。事实上,有些产品,比如F5网络公司的3DNS具有完整的DNS功能以及增强的GSLB特性,Foundry、Nortel、Cisco和Radware的产品能实现部分DNS功能。如果一个产品不能处理某些特定的DNS请求,它可能会选择丢弃请求,返回一个错误或者转发到一个真实的DNS服务器上。这对用户来说是个问题,一台智能DNS服务器的功能居然比不上普通的DNS服务器。
负载均衡器作为DNS转发代理
负载均衡器作为DNS转发代理的工作方式如图5.7所示,负载均衡器被注册为权威DNS服务器,而真正的权威DNS服务器部署在负载均衡器后面。负载均衡器将所有的DNS请求转发至真正的权威DNS服务器,并且修改权威DNS服务器返回的响应,从而实现GSLB。在这种方式中,如果有多台DNS服务器,负载均衡器就可以实现所有DNS服务器的负载均衡;如果只有一台DNS服务器,负载均衡器就只做简单的DNS请求转发。对外公布的权威DNS服务器的地址注册成负载均衡器上的VIP地址。DNS的常用端口53会和VIP关联,并与DNS服务器绑定。DNS服务器像往常一样响应客户的DNS请求,而负载均衡器会选择一个性能最好的站点并修改DNS服务器的响应,然后将响应转发给客户。负载均衡器只修改需要实现GSLB的域名的DNS查询响应。
图5.7 负载均衡器作为转发DNS的代理
这种方法可以获得服务器负载均衡所带来的好处,我们可以采用多台DNS服务器来提高可用性和扩展性。可以为DNS服务器配置私网地址且通过访问控制策略来提高安全性。而且,我们可以透明的从DNS服务器组里添加和删除DNS服务器。同时,负载均衡器不需要实现完整的DNS解析功能,只需要在解析过程中修改相应域名的DNS响应即可。此外,GSLB与本地服务器负载均衡可以同时存在,如图5.8所示,有两个不同的VIP:VIPD和VIP1。VIPD是权威DNS服务器注册的地址,而VIP1用作Web服务器群的虚拟地址。如果能够把TCP和UDP端口分开跟不同的服务器捆绑,那么权威DNS服务器和服务器群还可以共用一个VIP。
图5.8 负载均衡器同时实现GSLB和SLB
图5.9 真实授权DNS服务器不在同一地理位置的情况
使用DNS转发代理的方式,我们可以把DNS服务器放置在任意一个地方。比如说,有的客户想继续管理DNS服务器,就可以采用DNS转发代理的方式来实现GSLB。把负载均衡器上的VIP注册为权威DNS服务器,提供GSLB服务。客户能够继续管理DNS服务器并且随意更改它的配置。然而,如果权威DNS服务器在WAN上,并且与负载均衡器相隔很远,不管怎么样,负载均衡器向权威DNS服务器转发DNS请求都会产生额外的延时。一个简单的方法是,让负载均衡器把DNS响应缓存一段时间,就跟本地DNS服务器缓存权威DNS服务器的响应一样。比如说,在处理DNS解析请求时,负载均衡器可以将权威DNS服务器的响应缓存60秒钟。在接下来的60秒钟里,对于同一域名的所有后续请求,负载均衡器将会使用之前权威DNS服务器返回的响应,通过GSLB算法选择一个最好的站点,并且修改DNS响应里的地址。由于真正的DNS服务器与负载均衡器分布在不同的地方,负载均衡器必须使用源地址NAT来强制使响应返回到负载均衡器,从而能在返回给客户前修改DNS响应。
如果客户不想改变现有的DNS环境该怎么办呢?虽然采用DNS转发代理的方法比使用GSLB产品代替DNS服务器更胜一筹,但是仍需要将负载均衡器上的VIP注册为新的权威DNS服务器地址。解决方法是给负载均衡器分配一个新的VIP地址,并将其注册为权威DNS地址,或者将权威DNS服务器的地址作为负载均衡器的VIP,同时给权威DNS服务器重新分配一个不同的地址。无论采用哪种方法,都必须对现有的权威DNS服务器配置做一些改变。如果负载均衡器采用透明DNS代理的部署方式就不会对DNS系统配置产生任何改变。透明代理的方式在功能上与转发代理类似,只不过是透明的。
为了使用透明DNS代理的工作方式,负载均衡器必须部署在DNS请求和响应的必经之路上。所有的DNS请求和响应必须通过负载均衡器以便它能透明的截获DNS响应,并且更改DNS响应使其能返回最好站点的IP地址。只有配置了GSLB服务的域名,负载均衡器才会截获并做相应修改。
不管是DNS转发代理的方式还是DNS透明代理的方式,都提供了极大的灵活性,能把负载均衡器部署在DNS架构里,还能继续使用现有的DNS服务器,对现有DNS系统的改变也较小。同时负载均衡器不用实现DNS服务器全部的功能,当然,由于DNS服务器的存在,也没必要这么做。简单部署,让每种产品都能最大程度发挥它的作用。
5.4.2选择最好的站点
在本节,我们着重讨论几种选择最优站点的方法,分析其优势和不足。讨论完之后,我们再把不同的策略组合起来,从而选择出最佳站点。
有一点需要注意,DNS请求是本地DNS服务器发出的,不是实际的最终用户。广域网负载均衡器收到本地DNS服务器发出的DNS请求后,就必须根据当前获取的信息选择最好的站点,此时它并不知道实际最终用户的IP地址。大部分情况下,这是没问题的,因为本地DNS服务器要么与实际最终用户离的很近,要么与实际最终用户有相似的网络特性或网络延时。当然也有可能本地DNS服务器与实际用户相距很远,且它的响应时间和最终实际用户不同。在讨论站点选择策略之后,我们再详细的讨论这个问题。
站点健康状况
GSLB最重要的特性之一就是能够持续不断地监控站点的健康状况,并且只会将用户导向到正常工作的站点。这是比较容易实现的,因为GSLB中使用的健康检查功能与在服务器负载均衡中使用的健康检查是一样的。如果每个站点都有一台负载均衡器来实现服务器负载均衡,广域网负载均衡器就可以对VIP进行健康检查,如图5.10所示,服务器负载均衡器将广域网负载均衡器发过来的健康检查请求看作是普通用户的请求,并将其转发给后台的真实服务器。健康检查的类型有多种,就像服务器健康检查一样,从二、三层到四层,甚至是七层的健康检查。广域网负载均衡器能够根据用户指定的URL发送一个HTTP请求,并且可以检查返回的代码,在返回的内容中检查特定的关键字,或者对返回的页面作校验,并与用户指定的值进行匹配。
图5.10 GSLB设备的健康检查
站点响应时间
通过计算一个请求/响应的往返延迟时间,广域网负载均衡器能够计算出每个站点的响应时间。最简单的方法就是通过测量站点对健康检查的响应快慢来计算出站点的响应时间。注意,这个响应时间是从广域网负载均衡器到站点之间的往返时间,不是用户到站点的往返时间。再看一下图5.1,响应时间包含三部分。广域网负载均衡器测量出的响应时间和用户测量出的响应时间之间共同的部分是服务器端的响应时间,不包含客户端延迟和互联网延迟。
广域网负载均衡器测量出的站点响应时间实际上是一个站点里面最好的服务器的响应时间。当收到广域网负载均衡器发送的健康检查请求后,本地的服务器负载均衡器会将请求转发给压力最小的服务器,下一个请求,可能被转发到不同的服务器。由于每个请求的响应时间都是不同的,最好的办法是计算平均值。本地负载均衡器可以计算一个站点之内所有服务器的平均响应时间,并报告给广域网负载均衡器。
站点负载状况
在测量每个站点的负载状况并根据这些信息选择最优的站点时,我们不仅要考虑站点当前的负载,也要考虑站点的容量。由于每个站点的容量和当前的负载状况都不同,广域网负载均衡器将下一个请求导向到可用容量最多的站点是比较合理的。作为GSLB架构的一部分,每个站点的容量可能都是不一样的。比如在圣何塞数据中心有四台强大的服务器,能处理100,000个并发连接。而纽约数据中心只有两台中等的服务器,只能处理10,000个并发连接。此外,如何定义一个站点的负载是一个有争议的话题,我们在第二章负载均衡算法部分已经讨论过了。并发连接数是衡量一个站点负载的方法之一,也有人提出,不管站点的负载是多少,都能通过站点的响应时间反应出来。因此,通过站点响应时间衡量站点的负载状况是一个不错的选择。负载状况没有一个精确的定义,但只要是合理的,用它作为GSLB分发的依据,效果都会比标准DNS的要好。
比如说,我们使用并发连接数作为衡量站点负载和容量的标准,广域网负载均衡器收集并发连接数的信息来衡量站点当前的负载状况。然后广域网负载均衡器比较所有站点当前可用容量的比例,从中选择一个具有最大可用容量的站点。
当广域网负载均衡器把一个特定站点IP地址返回给本地DNS服务器之后,我们无法预测该站点会接收到多少新用户的请求。本地DNS服务器得到DNS响应后,将其缓存,为后续请求提供解析。可能是一个拨号用户,也可能是一个大型代理服务器,但是两者所产生的压力是截然不同的。
地理位置就近性选择
根据国家和大洲的不同,我们把IP地址空间划分成几部分。其中一部分由亚太网络信息中心(APNIC)负责管理,分配给亚太地区。一部分由美国网络地址注册管理组织(ARIN)负责管理,分配给北美地区,但不限于这些地区。另外一部分由欧洲网络资讯中心(RIPE NCC)负责管理,分配给欧洲和非洲地区。欲知更多详情,请参考HTTP://www.apnic.net/db/RIPs.html。
广域网负载均衡器在选择最佳站点的时候,它知道本地DNS服务器的IP地址。负载均衡器将本地DNS服务器所在的地址段与不同站点的地址段进行匹配。如果发起请求的本地DNS服务器的IP地址属于北美,广域网负载均衡器就把北美站点的VIP地址返回给本地DNS服务器。
这种方法可能不够精确,只能为用户提供粗略的就近性。另外也会有意外发生,比如本来属于北美的IP地址段被用在了别的洲。尽管存在上述问题,大部分用户还是选择接受这种算法。
地理位置就近性选择的站点对于用户来说并不一定是最好的站点,比如,由于美国互联网主干拥塞或者纽约站点压力大,纽约的用户访问东京的站点可能比访问纽约的站点速度更快。
响应时间就近性选择
从图5.1中可以看到,用户的响应时间由三个部分构成:客户端延迟,互联网延迟和服务器端延迟。服务器端延迟和用户的位置无关,而且广域网负载均衡器可以计算服务器端延迟。客户端延迟和Web站点地理位置无关,而且我们无法去控制。但是互联网延迟取决于客户端和Web站点的位置。为了测量互联网延迟,我们需要知道Web站点的位置和客户端的位置,找到一个办法测量站点和客户端之间的响应时间。Web站点的位置是已知的,但是我们不知道用户的位置。另外,用户的分布比较分散,遍及全球各地。有几种方法可以测量互联网延时,但是没有一种是完美的。我们先讨论几种不同的方法,然后把它们组合起来找出最理想的一种。
下面将要讨论的所有方法都要求广域网负载均衡器和本地负载均衡器支持一种特定的协议,以便它们之间能够互相通讯。
Ping
Ping是一个程序,常用来探测一个IP地址是否处于活动状态,也可以用来计算数据包的往返时间。当广域网负载均衡器收到DNS请求时,它会往每个站点的本地负载均衡器发送一个请求,让本地负载均衡器用Ping探测发起DNS请求的本地DNS服务器的IP地址。每个本地负载均衡器用Ping探测本地DNS服务器之后,将Ping的响应时间报告给广域网负载均衡器。广域网负载均衡器将会比较延时的大小,并选择响应时间最快的站点返回给本地DNS服务器。
这种方法的问题在于,广域网负载均衡器在收到每个本地负载均衡器的探测结果之前,是没有办法给本地DNS服务器返回结果的。虽然本地负载均衡器会同时发起探测,但是这个过程确实增加了DNS请求的延迟,潜在影响了用户体验。解决这个问题的方法是,广域网负载均衡器根据备选策略来返回结果,并且在后台继续收集Ping的响应时间。对于从同一个本地DNS服务器发来的后续请求,广域网负载均衡器就利用这些信息选择站点。采用这种办法增加额外的延迟,但是第一次请求得到的结果可能不是最好的站点。
采用Ping的办法还有其他的问题,首先,Ping不是一个准确的测量响应时间的方法。一旦网络上有流量拥塞,交换机和路由器可能会丢掉Ping包。其次,如果本地DNS服务器部署在防火墙后面,Ping请求可能无法到达。很多企业会在网络里部署防火墙来控制从外面进入网络的流量。如果本地DNS服务器部署在防火墙后面,放在企业网络的安全区域,防火墙可能阻止Ping请求。第三,互联网上的响应时间随着时间的变化而发生变化。现在我们可能测到Ping响应时间为50毫秒,但是十分钟后可能是500毫秒。所以测量某一刻的响应时间并不能代表某一段时间内的响应时间。
DNS Reply Race
使用这种办法时,广域网负载均衡器将DNS响应发送给所有的本地负载均衡器,而不是发送给本地DNS服务器。每个本地负载均衡器修改DNS响应,将它自己的VIP地址放置在DNS响应的首位,并且将响应转发给本地DNS服务器。本地DNS服务器会使用最先收到的响应,并且会丢弃后续的响应。但是本地DNS服务器接收到的第一个响应与站点和本地DNS服务器之间互联网延迟或许没什么关联。最先收到哪个请求由三个因素决定:广域网负载均衡器与本地负载均衡器之间的互联网延迟,本地负载均衡器修改DNS响应并转发给本地DNS服务器的延迟,以及站点和本地DNS服务器之间的互联网延迟。既然我们的目标是根据第三个因素,即站点和本地DNS服务器之间的互联网延迟来作为选择站点的依据,我们可以降低前两个因素造成的影响。我们的目标是让所有的本地负载均衡器同时发送响应,这样一来本地DNS服务器最先收到的响应就来自与本地DNS服务器之间延迟最小的站点。但这只是最理想的状态,或多或少总会有些差异。同采用Ping的方式一样,这种方法也是基于某一刻互联网延迟来选择最佳的站点,而不是基于某一时间段内的平均网络延迟。
TCP响应时间
使用这种算法时,广域网负载均衡器第一次收到本地DNS服务器的请求之后,不根据响应时间选择站点,只简单地使用其他任意一种策略选择一个站点。当用户访问此Web站点时,本地负载均衡器测量客户端与Web站点之间的TCP SYN和TCP ACK之间的延迟。这里本地负载均衡器不会产生任何流量,它只是根据客户端到站点之间正常的流量来测量响应时间。即使本地DNS服务器部署在防火墙后面,这个办法也能生效,因为本地负载均衡器不会对客户端发起任何流量。这非常像我们在第二章讨论过的服务器健康检查,并且这种办法非常高效。由于用户会访问不同的Web页面,建立很多的TCP连接,本地负载均衡器能够测量一段时间之内的响应时间,每次测量都是一个数据点。为了避免收集太多的数据点,本地负载均衡器可以对每十个或者二十个连接取样一次。用这个办法可以很好的收集用户与站点之间的响应时间,并且能够反映互联网延迟。然而,这种方法测量的是在广域网负载均衡器为用户选定一个站点后的响应时间。
由于是广域网负载均衡器负责最终的域名解析,所以一旦本地负载均衡器收集到响应时间,它需要将这些数据传送到广域网负载均衡器。这需要在本地负载均衡器和广域网负载均衡器之间有一种特定的协议。当用户被引导到一个特定的站点进行访问时,用这个办法就可以计算站点和用户之间的延迟时间。为了对比不同站点的响应时间,还需要测量同一个用户到其他每个站点间的延迟时间。这只能通过将同一个用户分别引导至每个站点去访问的办法来获取这些延迟时间。这个过程比较漫长,而且需要客户端重新发起对这个Web站点的访问,并且触发DNS请求。如果在同一个网络能找到其他用户的话,就可以直接把第二个用户引导至其他的站点来测量网络延迟。这样,就可以让相同网络中的不同用户去访问不同的站点来收集数据,然后通过比较延迟时间来确定哪个是最佳的站点。
注意这个办法测量的是真实用户与站点间的TCP响应时间。可是广域网负载均衡器是从本地DNS服务器接收到DNS请求,而不是从真实的最终用户。这里涉及到两个不同的IP地址:本地DNS服务器的IP地址和真实最终用户的IP地址。我们需要找到一个办法把这两个IP地址关联起来,以便于广域网负载均衡器能根据真实用户的响应时间返回给本地DNS服务器一个最佳的站点。当一个用户与一个站点建立TCP连接时,本地负载均衡器并不知道用户本地DNS的地址。同样地,当广域网负载均衡器接收到本地DNS服务器的请求时,它也不知道位于本地DNS服务器后面真正最终用户的地址。但是,如果能够将用户与本地DNS服务器归为一组,我们就可以把某个最终用户的响应时间作为整个组的响应时间。如果组里有5,000个用户和20台本地DNS服务器,至少需要一个客户端通过访问每个站点的方式来收集一组TCP响应时间。然后广域网负载均衡器通过比较这些响应时间来选择一个最佳的站点。那么,要想使用这种方法,最大的挑战就是定义一个包含最终用户和本地DNS服务器的组。很明显,这种方法的是否有效就取决于这个组定义的好坏。
我们可以使用IP地址的前几位,类似网络地址的方法来识别一组用户及其本地DNS服务器。跟网络地址一样,我们可以定义一个IP前缀长度来识别一个用户组。例如,如果长度是24,那么IP地址的前24位就是组标识。这样的话,IP地址192.168.21.1和192.168.21.2一直到192.168.21.254都属于组192.168.21。如果IP前缀长度是24,这个组就包含254个用户,因为0和255不是合法的IP地址。通过计算一个用户与站点之间的TCP响应时间,将结果作为组里所有用户解析的依据,这样就不用计算每个用户到站点之间的延时了。
关于组的概念还需要以下条件作为前提,首先,对于组里的所有用户来说,互联网延迟是相似的。其次,本地DNS服务器的地址也在这个组里。也就是说,192.168.21这个用户组的本地DNS服务器是192.168.21.1到254之间的某一个IP地址。这都是非常大胆的设想,可能对,也可能不对。但是这种方法的优势在于,我们可以通过改变IP前缀长度来增大或者减小用户组的大小。例如,IP前缀为23的组的大小是前缀为24的组的两倍。用户组越大,意味着需要测量的数据越少,但是风险也相应增加,因为对于组里所有用户来说,互联网延迟并不是完全相同的,组里一个用户的互联网延迟可能与另外一个用户有很大的差别。
上述方法最重要的一点是,通过分组的方式,我们可以从一些样本用户那里获取响应数据,作为其他用户解析的依据,提高了效率。随着时间的推移,更多的用户去访问不同的站点,本地负载均衡器收集到越来越多的信息,这就能更好的计算出响应时间。但是我们需要找出一个巧妙的方法来将互联网用户分成不同的组,让每组用户访问一个站点都有相似的互联网延迟。当数据包从A发送到B时,路由器能计算出最佳路径,是因为它能识别出不同的地址段。如果每一个单独的IP地址都需要路由器维护一条路由的话,那路由表将是巨大的。所以,每个地址段维护一条路由,目的地址属于这个地址段的所有的数据包路径都是一样的。换句话说,地址段内的所有用户的路由特征都是相同的。而这正是我们期望广域网负载均衡器能够实现的:将互联网用户划分为不同的的组,并且每个组都具有相似的网络延迟特征。我们可以使用BGP路由器上面的地址段。为了获得所有的路由表信息,广域网负载均衡器需要和路由器一样,必须运行BGP协议。或者广域网负载均衡器和其他的BGP路由器之间有一个私有的协议,用来获取路由表信息。无论哪种方法,广域网负载均衡器只要能获得地址段,就可以跟BGP路由器一样把互联网用户进行分组。采用这种地址段分组方法,一组用户及其本地DNS服务器属于同一个地址段的几率大大增加。
到目前为止,我们讨论了把互联网用户按地址段分组并测量响应时间的方法,这种方法看起来还不错,但是也存在问题。假设有三个站点参与GSLB,对于某个地址段内用户发起的第一个DNS请求,返回站点1的地址;对于第二个请求,返回站点2的地址;对于第三个请求,返回站点3的地址。由于用户访问不同的站点,本地负载均衡器将响应时间的数据汇报给广域网负载均衡器。假定地址段内的用户到站点2的响应时间更快,广域网负载均衡器会将地址段内用户后续的所有DNS请求引导至站点2。只要地址段内还有用户去访问站点1和站点3,广域网负载均衡器就能继续获得到站点1和站点3的响应时间,并且在站点选择策略上作出相应的调整。但是如果最开始被引导至站点1和站点3的用户结束了它们的会话,广域网负载均衡器将不会再获得用户到站点1和站点3的响应数据。根据之前计算的结果,广域网负载均衡器会将后续所有的用户的引导至站点2。即使用户到站点1和站点3的响应时间得到改进,并且比到站点2的响应时间更小,广域网负载均衡器也无法得知。为了防止这种现象的发生,广域网负载均衡器必须周期性地至少将一个用户分别引导至站点1和站点3,以便获取站点1和站点3响应时间的变化。如果站点1和站点3的响应时间还是相当差的话,这些用户的访问体验将会很差,但这是唯一能获取站点响应时间变化的方法。
测量TCP响应时间还有一种方法,就是在互联网上不同的位置部署监测点,实际上就是运行特定监测程序的计算机,它们会周期性的跟不同的站点建立TCP连接,触发每个站点的本地负载均衡器测量TCP响应时间。不管每个地址段内是否有用户去访问不同的站点,广域网负载均衡器都会保证响应数据是最新的。这样的话,在某个用户第一次访问Web站点之前,广域网负载均衡器就已经获得了响应时间的数据。最大的挑战就是在互联网上部署足够多的监测点,能够覆盖所有的地址段。我们可以先在大地址段内部署监测点,然后循序渐进慢慢增加。CDN服务提供商,如Akamai,和Web站点性能监测服务提供商,如Keynote,也是出于类似的目的,采用监测点这种方式。
路由开销
广域网负载均衡器和本地负载均衡器能够识别BGP,并且计算站点与地址段之间BGP路径开销或者自治域系统的跳数。自治域系统在RFC1772里有详细地定义,是指在单一技术管理体系下的多个路由器的集合,在自治系统内部使用内部网关协议(IGP)和通用参数来决定如何路由数据包,在自治系统间则使用AS间路由协议来路由数据包。路由开销用来衡量用户与站点之间网络路径的长度,但是路由开销跟响应时间并不总是相对应的。有的网络路径很短,但是网络很拥塞,而有的路径较长,但是网络相对空闲,可以提供更好的响应时间。采用路由开销的优势在于它可以计算出来,并且不需要用户去访问任何站点。这个策略是个很好的起点,我们可以在此基础上进一步优化,作为根据响应时间选择站点的依据。
静态指定就进性
对于一个已知的地址段,我们可以预先定义就近性规则,将该地址段内的用户导向一个指定的站点。比如,我们可以为某个特定的企业用户定义就近性规则,将其引导至一个指定的站点,只要这个站点是正常工作的。静态指定就近性的方法也可以用来优化前面讨论过的地理位置就近性的策略,如果负载均衡器只能识别一个洲的地址段,而不能区分每个国家的话,我们可以使用静态指定就近性的方法,将某个特定国家的地址段内的用户导向一个指定的站点。
容差
根据某项指标对站点进行对比时,比如响应时间或者站点负载状况,可能差距比较小。例如,对于同一个地址段内的用户来说,站点1的响应时间是100毫秒,站点2的响应时间是99毫秒。根据负载均衡算法,广域网负载均衡器会一直选择站点2,如何避免这种情况呢?容差就是解决这个问题的,它是一个百分比,即当采用指标来比较不同的站点时,负载均衡器允许的上下浮动的范围。
选择最好的站点
到目前为止,我们已经讨论了几种选择站点的方法,接下来我们把它们组合起来,对其进行优化。
首先,用排除法选择站点,广域网负载均衡器根据用户定义的站点选择策略来逐步排除不符合要求的站点。例如,假设有三个站点:站点1、站点2和站点3;广域网负载均衡器基于站点健康状况,负载状况和TCP响应时间来选择最佳的站点。广域网负载均衡器首先排除不能提供服务的站点,然后基于负载状况选择排除处理能力较差的站点。最后,根据TCP响应时间在剩余的站点中选择一个最好的。如果还是有多个选择的话,广域网负载均衡器会采用默认的方法来选择站点,比如说轮询法。
其次,用加权法来选择站点,可以跟排除法一起使用。首先,健康检查可以排除不能提供服务的站点,然后我们进一步用其他方法排除站点,比如基于负载状况或者基于地理位置的方法,缩小选择的范围。每一项指标,我们都可以定义一个权重值,例如,给TCP响应时间分配一个较高的权值,为路由开销分配一个较低的权值,这样就可以同时考虑多个指标,从而选择最佳的站点。
选好了站点之后,广域网负载均衡器有两种选择,它可以只回复给本地DNS服务器这个站点的IP地址,或者回复给本地DNS服务器一个地址列表,并将这个站点的IP地址放在第一位。如果选择第一种方式,广域网负载均衡器返回给本地DNS服务器结果之后,如果相应的站点突然发生故障,这时就只能等浏览器和本地DNS服务器保存的记录过期,重新发起解析。如果广域网负载均衡器返回一个地址列表,并且将最好的站点置于首位,本地DNS服务器会把第一个IP地址返回给第一个发出请求的客户端,在TTL值过期之前,收到相同域名的后续请求时,很多本地DNS服务器会以轮询方式从地址列表里选择一个IP地址返回给客户端,就不一定是最佳的站点。有一个折中的方法,广域网负载均衡器在回应时只提供列表里面的前三个IP地址。
对站点选择算法的优化是没有止境的,有时也不必最大限度的进行优化。最好就是使用80-20原则,用20%的努力来获得80%的好处。
GSLB负载均衡效果的好坏取决于有的多大比例的用户被导向性能最佳的站点,如果用标准DNS轮询的方法,这个比例是非常低的。用不同的策略时,这个比例也会相应有所变化,不过要测定广域网负载均衡器效果的好坏是相当困难的。
5.4.3 基于DNS的GSLB的局限性
受DNS工作机制的影响,基于DNS的GSLB有其局限性。当然,DNS本身就不是为了GSLB而设计的,我们只是在它的基础上进行扩展。
首先,最终用户可能与本地DNS服务器相隔很远,也就是说它们到同一个站点的网络延迟可能相差很大。使用基于DNS的GSLB,很难解决这个问题。具体有多少用户存在这个问题还没有办法统计,最常见的情形就是,一个企业用户手动配置了本地DNS服务器的IP地址,当这个用户移动到其他地方的时候,会继续使用这个本地DNS服务器。对于有些企业来说,如果企业采用的是集中式的互联网接入,这可能根本没影响。不管怎么说,越来越多的网络使用DHCP,这就大大增加了本地DNS服务器靠近用户的可能性。不管本地DNS服务器和用户与站点间的互联网延迟是否相似,记住这里的术语“近”和“远”并不是指物理上的距离,而是网络距离。有一种情况人们经常理解错误,就是当企业用户从一个远程分支拨入企业网络的时候。比如我到了日本,通过拨号连接到Foundry内部网络,然后我就与Foundy在San Jose总部的计算机在同一个网络中了。这是因为我所发出的网络流量都会通过拨号连接,由Foundry的远程接入服务器进行处理。我虽然在日本,但是互联网延迟却跟Foundry在San Jose的内部用户是一样的。不同的是,客户端延迟可能会比较长,这是由从日本到Foundry办公室的物理线路造成的。
其次,有些本地DNS服务器并不规范,会忽略DNS纪录的TTL值,无限期的缓存DNS纪录,给用户提供的都是过期的解析结果。
第三,浏览器会缓存DNS纪录,除非关掉或者重启浏览器。如果电脑和浏览器在几天之内一直工作的话,浏览器将会持续访问同一个站点,尽管其他站点可能会提供更好的响应时间。
第四,在权威DNS服务器返回给本地DNS服务器解析结果之后,站点的健康状况可能会发生变化。如果站点还能够提供HTTP服务的话,可以通过HTTP重定向,将用户定向到另一个站点,不过这仅限于HTTP应用。如果站点不能提供任何服务的话,我们只能祈祷用户浏览器的DNS纪录尽快过期。否则,必须重启浏览器才能触发其重新发起DNS请求。
无论DNS架构本身有什么样的局限性,基于DNS的GSLB还是具有很多优点,弥补了标准DNS的不足。
5.5 基于路由协议的GSLB
基于路由协议的GSLB在DNS体系之外工作,当然也会有它自己的问题,服务提供商或者企业内部网络可以采用这种方法。不管怎么说,这种实现GSLB的方法都非常有趣,两个不同的站点使用同一个IP地址,一旦DNS服务器把域名对应的IP地址返回给用户之后,就可以用这种办法把请求引导至最佳的站点。
图5.11 使用路由协议的GSLB
基于路由协议的GSLB的工作原理如图5.11所示,有两个负载均衡器,A和B,放在不同的站点,每个负载均衡器都跟两台真实服务器相连。两个负载均衡器上配置相同的VIP地址。这时需要负载均衡器具有一些特殊的功能,如果它能够处理访问VIP的请求,它需要让VIP可用,也就是说,路由器能够通过ARP请求知道这个VIP,并且能够Ping通它。为了让VIP可用,负载均衡器需要确认至少有一个真实服务器是正常工作的。
如果VIP是可用的,路由器就会认为这个地址是可达的,也就是说,路由器知道如何将数据包包发送到这个地址,这个过程可能会贯穿整个网络。如果两个站点中负载均衡器上的VIP都是可用的,路由器只会将此看作到同一个IP地址的两条不同路由。
当客户端A输入URL访问Web页面时,首先通过DNS系统把域名解析成VIP。客户端向VIP发送请求会穿过用户的网络进入用户ISP的网络,最终进入VIP所在ISP的网络。请求通过边缘路由器A进入网络,路由器A查看路由表来决定通过哪条路径转发数据包至VIP。它会发现有两条不同的路由,最后基于路由协议算法选择一条路由。路由协议算法有很多种,比如OSPF(开放最短路径优先),它为每条可达路径计算路由开销,并且选择最低开销的路径。在图5.11的例子中,路由器A选择一条通向负载均衡器A的路径。同样地,路由器B会选择一条通向负载均衡器B的路径,用来转发客户端B发来的数据包。
互联网是基于包交换的网络,任何两个端点间都可能存在多条路径。路由协议,如OSPF,为每个数据包选择一条最好的路径,然后转发数据包。在这种GSLB的实现方法中,我们只不过是利用了路由器内置的功能。路由器选择的路径决定了处理这个请求的负载均衡器。
对于这种实现方法,需要注意以下几个问题。首先,当用户在访问Web站点时,会打开和关闭一系列的TCP连接。这些连接在网络层被封装成一系列的数据包,在客户端和负载均衡器之间进行交换。路由器将每个数据包都看成是独立的,并不关心它是否属于同一个连接。为了保证客户端和负载均衡器之间能够正常通信,从一个客户端发送的所有数据包都必须发送到同一个负载均衡器上。也就是说,一旦路由器选定一条路径将客户端的第一个数据包发送到VIP,后续的数据包也必须使用相同的路径,否则通信会中断。当有多条路径存在时,有些路由器会采用负载分担的方式,同时通过多条路径转发数据包。为了让这种GSLB方法能够正常工作,需要在路由器上禁用上述功能。
理想的状态下,所有路径的路由开销是不变的。由于路由开销不变,路由器为每个数据包都选择相同的路径。但现实中,很少会出现这种情况。任何一个链路的故障,或者过度拥塞,都有可能导致路由开销的变化。最终结果就是,路由器在转发数据包时,可能突然从一条链路转移到另外一条链路上。也就是说,客户端A发送的数据包开始转发到负载均衡A,但中途突然转发给负载均衡器B。这不仅会中断当前的连接,而且会中断会话保持,丢失所有的用户信息,比如购物车信息等。如果网络状况经常发生变化,采用这种方案的话,转发数据包的路径就会经常变化,用户的体验会非常差。所以,这种设计方案只适合在网络状况稳定的环境下使用。
如果负载均衡器或者服务器故障导致一个站点中的VIP不可达,去往这个VIP的路由就失效了,就是我们常说的路由回收。有的负载均衡器或者路由器有一些内置的特性,可以加速路由回收的过程。路由的回收需要传播至网络云中所有相关的边缘路由器,这个过程也被称作路由收敛。路由收敛的时间取决于网络的规模,如果网络规模大,可能需要几分钟。所以,将这种GSLB的实现方法仅限于在路由收敛时间可预测并且足够快的网络环境中。如果负载均衡器A发生故障,客户端A继续尝试与VIP建立TCP连接。TCP协议中设置了计时器,如果对方没有响应,它会重试发起连接。如果路由收敛的时间比TCP默认的超时时间长,用户必须通过重新点击超链接或者在浏览器上按刷新按钮来重试。
默认情况下,路由信息都是基于网络地址的。例如,假设子网141.122.10.*中有200台主机,*可以是1到254中任意一个数字,所有的主机都连接到路由器A上。网络中连接到路由器A的其他路由器只需要维护一条路由即可,141.122.10.*中任何一个IP的数据包都发送到路由器A。如果为子网141.122.10.*中200台主机每台主机都维护一条路由,路由器需要维护200条路由,而且每条路由下一跳都是路由器A。这最终会导致路由表体积过于庞大,并且难于管理。默认情况下,大多数路由器都不维护单台主机的路由。但是为了让基于路由协议的GSLB能正常工作,每台路由器都必须维护一条到VIP的主机路由。只有个别网络允许主机路由,大部分运营商为了控制路由条目的数量,都会丢弃主机路由。因此,这种GSLB方案只能在单个运营商或者企业网络内部使用。
基于路由协议的GSLB是一个非常有趣的方法,但这种方法需要一个可控的网络环境,并且需要维护网络的管理员以及维护负载均衡器和服务器的网络管理员之间的互相协作才能实现。
5.6 小结
GSLB是一个非常强大的工具,它不仅能跨越多个站点获得高可用性,还能够扩展系统容量并且改善用户的响应时间。比起基于路由协议的GSLB方案,基于DNS的GSLB方案虽然有其局限性,但简便易行,所以更受人欢迎。如果把基于DNS的GSLB和基于路由协议的GSLB结合起来,可能会得到一个完美的解决方案,但是这十分复杂,超过了这本书讨论的范围。(可能会在本书的后续版本讨论这个话题)
尽管有这么多的优势,GSLB的应用还是没有服务器负载均衡那样普遍。首先,GSLB很难理解,而且还需要DNS的基础知识。其次,如果应用需要使用数据库,并且在用户交易的过程中不断更新的话,那么不同站点间的数据库需要实时同步,这个问题很难解决。为了安全地同步数据库,就需要在站点之间使用加密的虚拟专用网络或者专线。
有些DNS服务提供商可以为指定的域名提供智能解析的服务。这样就不用学习并维护复杂的GSLB产品了,但这种服务的成本比较高。希望服务提供商能够找到更有效的运营模式来降低成本,我们期待着服务降价的那一天。

--------------------------------------------------------------------------------------------------------------------------------------

版权所有,转载请注明出处  京ICP备2021040351号