60分钟

第8章 负载均衡

【学习目标】

1.知识目标

理解负载均衡的概念。

理解网络层负载均衡与七层负载均衡的异同。

掌握等值路由负载均衡技术的原理及部署。

理解基于DNS的全局负载均衡技术的实现原理。

掌握Keepalived负载均衡产品的实现原理及部署。

理解HTTP协议的结构及主要HTTP头的作用。

掌握HAPorxy负载均衡产品的实现原理及部署。

2.技能目标

能够运用网络复杂均衡技术实现服务容量的优化部署。

能够运用Keepalived产品实现服务器的负载均衡及容错部署。

能够运用HAProxy技术实现服务器应用层的负载均衡及容错部署。

【认证考点】

负载均衡技术的分类。

网络负载均衡技术的实现原理及应用场景。

七层负载均衡技术的原理及应用场景。

Keepalived的配置及部署。

HAProxy的配置和部署。

项目引导:电商网站的负载均衡集群部署

【项目描述】

本项目模拟一个电商网站Web前端服务器的部署,该网站内容分为静态数据和动态数据量部分,静态数据主要是商品图片、企业形象、前端样式、前端脚本代码等不经常变化的内容,案例中通过静态文本方式进行模拟,并使用Apache服务器提供服务。动态内容主要是广告数据、用户信息及用户购买行为所产生的数据,案例中通过在页面中嵌入时间及服务器主机名方式进行模拟,并使用Tomcat JSP动态页面来产生,本案例通过综合等值多路径负载均衡技术、Web服务器的安装及部署、Tomcat的安装及部署、Keepalived四层负载均衡及HAProxy七层负载均衡产品的安装及部署,实现网站服务的平滑扩展能力及容错能力。

知识储备

8.1 负载均衡概念及类型

在计算机系统和互联网发展的早期,使用计算机来完成的业务流程,通常具有业务逻辑简单,数据量小,网络带宽消耗小的特征,大部分系统采用单台服务器就能够满足业务的需求,在这个时期,根据业务规模的大小不同,企业服务器通常使用大、中、小型机服务器来承担,但随着互联网的发展,业务数据量越来越大,业务逻辑也越来越复杂,业务流程越来越依赖于企业的信息化系统,单台服务器的性能问题以及单点问题凸显了出来,而采购更为复杂的超级计算机成本无疑是高昂的。这时业界开始用多台计算机进行分布式计算这种水平扩展方式来避免单点故障,这样的计算机系统就需要解决如下问题。

1.网络带宽的扩展问题

由于技术发展水平的限制,在某个时间范围内,我们计算机网络使用的物理传输介质以及网络处理芯片存在各种限制,导致单个物理传输介质上的最大传输能力不够,以及单个网络设备的端口密度和处理能力的不足,在这种情况下,发展出各种网络负载均衡技术实现网络处理能力的扩展,主要技术包括:

(1)链路捆绑技术

(2)等值路径负载均衡技术

2.服务器处理能力的扩展

同样的,受制于技术发展水平的限制,服务器的计算、存储性能也不可能无限扩展,当单个服务器不能满足业务的并发处理需求的时候,也需要通过多台服务器来扩展系统的处理能力,这就是服务器负载均衡技术,服务器负载均衡技术主要包括以下类型:

(1) DNS负载均衡

(2) 网络层负载均衡

(3) 七层负载均衡

8.2 网络负载均衡技术

8.2.1 链路捆绑技术

1.链路捆绑的基本概念

以太网链路聚合简称链路聚合,它通过将多条以太网物理链路捆绑在一起成为一条逻辑链路,从而实现增加链路带宽的目的。同时,这些捆绑在一起的链路通过相互间的动态备份,可以有效地提高链路的可靠性。如图8-2-1所示,Device A与Device B之间通过三条以太网物理链路相连,将这三条链路捆绑在一起,就成为了一条逻辑链路,这条逻辑链路的带宽等于原先三条以太网物理链路的带宽总和,从而达到了增加链路带宽的目的。同时,这三条以太网物理链路相互备份,有效地提高了链路的可靠性。

图8-2-1 以太网链路聚合

将多个以太网接口捆绑在一起所形成的组合称为聚合组,而这些被捆绑在一起的以太网接口就称为该聚合组的成员端口。每个聚合组唯一对应着一个逻辑接口,我们称之为聚合接口。聚合组/聚合接口可以分为以下两种类型:

(1) 二层聚合组/二层聚合接口:二层聚合组的成员端口全部为二层以太网接口,其对应的聚合接口称为二层聚合接口(Bridge-aggregation Interface,BAGG)。

(2) 三层聚合组/三层聚合接口:三层聚合组的成员端口全部为三层以太网接口,其对应的聚合接口称为三层聚合接口(Route-aggregation Interface,RAGG)。

2. 聚合模式

根据成员端口上是否启用了自动协商功能,可以将链路聚合分为静态聚合和动态聚合两种模式。

(1) 静态模式

在静态聚合模式下,聚合组内的成员端口上不启用自动协商,其端口状态通过手工进行维护,其优点在于对设备要求低,设备CPU开销小,缺点在于容易出错,不能避免网络设备端口假死状态下的网络异常及故障。

(2) 动态模式

在动态聚合模式下,聚合组内的成员端口上均启用LACP协议,其端口状态通过该协议自动进行维护,其优点在于设备间自动协商,在端口连接错误、设备端口假死的状态下,都可以避免聚合的发生,从而避免网络故障,而缺点在于对设备要求较高,对网络设备的CPU性能有一定的消耗。

3. 负载均衡的模式

链路捆绑根据网络设备厂家的不同,其负载均衡的算法有所不同,主流的均衡算法包括:

(1) src-mac,根据以太帧源MAC地址Hash结果选择。

(2) dst-mac,根据以太帧目的MAC地址Hash结果选择。

(3) src-dst-mac,根据以太帧源目的MAC地址Hash结果选择。

(4) src-ip,根据包的源IP地址Hash结果选择。

(5) dst-ip,根据包的目的IP地址Hash结果选择。

(6) src-dst-ip,根据包的源目的IP地址Hash结果选择。

(7) src-prot,根据包的源IP地址加端口Hash结果选择。

(8) dst-port,根据包的目的IP地址加端口Hash结果选择。

(9) src-dst-port,根据包的源目的IP地址加端口Hash结果选择。

这些负载均衡算法,从上到下,其均衡性能也是从差到好。

4. 链路捆绑技术的应用场景

链路捆绑技术,主要运用于交换机之间或者服务器和交换机之间扩展互联的带宽,较少用于多服务器的负载均衡。

8.2.2 多路径负载均衡技术

1. 基本概念

在传统的路由技术中,发往单个目的网段的数据包只能利用其中的一条链路,其它链路处于备份状态或无效状态,对于网络带宽来说,存在较大的浪费,为了解决这样的问题,网络设备的厂家推出了一种多路径路由 (Multipath Routing) 技术,该技术可以在存在多条链路到达同一目的网段的时候,允许同时使用多条链路进行数据转发,不仅增加了传输带宽,并且可以提供链路备份的数据传输能力。

2. 实现方法

多路径路由负载均衡技术分为两种。

(1) 等值多路径路由技术

在上面两种多路径路由均衡技术中,由于不等值多路径路由技术在流量分担权重算法方面存在一定的困难,未得到广泛运用。实际工作者运用得最多的是等值多路径路由技术,该技术在动态路由或静态路由技术的基本上,静态配置或动态学习到目的网段的多个下一个转发节点,从而实现在多路径上的流量分配。

(2) 不等值多路径路由技术

不等值多路径路由技术较少用于实际环境,这里就不具体介绍了。

3. 负载均衡的算法

在如何确定到特定目的网段的流量具体使用哪一条路径进行转发的时候,多路径路由均衡算法使用了和链路捆绑算法类似的机制,即通过对网络流量特定字段的Hash计算结果来确定转发的路径,不同的设备厂家实现的算法有一定的差别,主要的算法包括:

(1) src-ip,根据包的源IP地址Hash结果选择。

(2) dst-ip,根据包的目的IP地址Hash结果选择。

(3) src-dst-ip,根据包的源目的IP地址Hash结果选择。

(4) src-prot,根据包的源IP地址加端口Hash结果选择。

(5) dst-port,根据包的目的IP地址加端口Hash结果选择。

(6) src-dst-port,根据包的源目的IP地址加端口Hash结果选择。

4. 应用场景

多路径路由负载均衡算法除了用于网络上的负载均衡及容错外,还可以用于服务器的负载均衡,其主要的实现原理如下:

服务器配置动态路由技术,在物理接口或环回接口上配置虚拟IP,并通过动态路由宣告到网络中,当多个服务器都宣告同样的虚拟IP的时候,并且网络设备配置了等值多路径负载均衡时,网络设备就可以将流量分担到不同的服务器上。

由于动态路由的自动拓扑发现和超时机制,当服务器故障的时候,故障服务器产生的路由将会从路由表的消失,从而引起网络流量的重新分配,避免将流量发送到失效服务器而引起的服务不可用故障。

多路径负载均衡技术用于服务器负载均衡存在下面的缺点或限制。

(1) 负载均衡算法的选择

大多数情况采用的负载均衡算法为源目的IP地址,只有这样的算法,才能让某个客户端IP的所有请求都能够分配到同一台服务器上,如果采用了基于端口的负载均衡算法,就可以能引起某个客户端的不同请求被分配到不同的服务器上,导致服务器会话状态数据的丢失,可能引起业务逻辑上的失效。如果服务器之间存在会话状态的同步机制或者客户机的请求之间没有关联的话,基于端口的负载均衡算法也是可行的。

(2) 路由波动引起的问题

如果服务器故障或者服务器故障后恢复,都可能导致负载均衡Hash计算值与服务器之间的映射规则发生变化,导致客户端会话被分配到不同的服务器上,从而导致用户会话信息的丢失,使得客户端以前的部分操作失效。这也是这种技术的最大缺点。

(3) 转发路径的一致性问题

由于网络中可能在多个节点上存在使用不同负载均衡算法的多路径负载均衡技术,如果到达服务器的流量,通过多于一个网络节点进行转发时,会存在不同节点均衡算法的映射关系不同,导致同一用户的请求被分配的不同服务器的问题,因此,需要在网络中仔细规划,确保到达服务器的流量,最后一跳是通过同一个路由节点进行转发的,这样才能解决负载均衡的一致性问题。

8.3 服务器负载均衡技术

服务器负载均衡(Server Load Balance,简称SLB)是一种服务器集群技术。服务器负载均衡将特定的业务分担给多个服务器,从而提高了业务处理能力,保证了业务的高可用性。负载均衡基本概念有:实服务、实服务组、虚服务、调度算法、持续性等,其常用应用场景主要是服务器负载均衡。

服务器负载均衡根据设备处理的机制的不同,分为DNS服务器负载均衡、四层服务器负载均衡和七层负载均衡,DNS负载均衡模式通过将单个域名映射到多个IP地址,并将不同的IP地址响应给不同的客户端,达到将不同的客户请求分派到不同的服务器上来实现服务器的负载均衡;四层负载均衡技术通过对IP包IP源目的地址及传输层端口进行处理,将不同的用户请求分配给不同的服务器来实现;七层负载均衡技术处理到报文载荷部分,比如HTTP、RTSP、SIP报文头,有时也包括报文内容部分,通过这些应用层信息,将客户端请求映射到不同服务器进行处理。

8.3.1 DNS负载均衡技术

DNS负载均衡技术的原理是通过对不同客户端响应不同的DNS域名与服务器IP的映射关系,从而实现将不同的客户端引导到不同的接入服务器,其在当今互联网场景的主要应用是实现服务器的就近接入,即我们通常所说的服务器全局负载均衡技术。

采用全局负载均衡(GSLB)的前提是在不同地区设立了多个数据中心,并不是所有的互联网服务都能做GSLB,实施全局负载均衡可能需要以下前提:

(1) 业务与用户弱相关,即无论用户从哪个IDC访问都能得到相同的结果。

(2) 或以地域划分用户,用户不会出现跨区域流动访问的情况,只会访问就近IDC。

(3) 有一套入口调度或者内部调度机制,能将用户调度到所属的系统。

(4) 用户数据能强一致性同步,并有一套数据同步失效的预案。

全局负载均衡关键的技术是智能DNS,它可以通过多种负载均衡策略来将客户端需要访问的域名解析到不同的数据中心的不同线路上,比如通过IP地理信息数据库解析到最近的线路,或者权衡不同线路的繁忙度解析到空闲的线路等等。目前国内智能DNS服务商提供的服务通常使用发HTTP请求的健康检查的方法去检测服务的过载情况,通过GSLB与服务器联动,实时感知的线路和后端情况。下面是一个基于DNS负载均衡的GSLB部署案例,DNS的解析步骤如图8-3-1所示。

图8-3-1 基于DNS的负载均衡案例

(1) 用户向本级配置的本地DNS服务器发出查询请求,如果本地DNS服务器有该域名的缓存记录,则返回给用户,否则进行第⑵步;

(2) 本地DNS服务器进行递归查询,根据是否有上级域名的DNS缓存数据,决定下一步查询的DNS服务器,如果没有缓存,则查询互联网上的根DNS服务区,一般来说,根DNS不会有二级或三级域名的缓存信息,这种情况下,根DNS会返回一级域名的NS记录,即图中的第⑵步;

(3) 本地DNS根据根DNS服务器返回一条NS记录,继续查询一级DNS服务器,二级域名也会返回下级域名的NS给本地DNS,直到本地DNS找到具体域名的内容提供商DNS,即图中的第⑶步;

(4) 本地DNS服务器向其中一个内容提供商DNS服务器发出域名查询请求;内容提供商的DNS通常具备GSLB(全局负载均衡)能力,根据GSLB策略的不同,内容提供商的DNS服务器会根据用户本地DNS服务器的地址判断客户所在的网络位置,然后根据内容提供商的业务提供点、负载情况,选出最优解析结果,返回一条A记录给本地DNS服务器,即图中的第⑷步。

(5) 本地服务器将查询结果通过一条A记录返回给用户,并将缓存这条记录,即图中的第⑸步。通过DNS解析报文中的TTL(Time To Live)字段可以控制客户端缓存这条记录的时间,在缓存时间内客户端会使用旧的查询结果,当缓存时间超时后才可能重新发出查询,TTL值过大会导致故障发生时切换时间过长,TTL值太小会造成查询频繁,对设备和网络的压力增大。

(6) 由于内容提供商能够根据客户端所处的网络位置及自身的服务提供点的数据,动态响应DNS记录,这样,内容提供商就可以为不同区域的用户提供不同的内容接入点,从而实现负载均衡。

8.3.2 四层服务器负载均衡技术

四层服务器负载均衡技术是通过网络层和传输层的信息来决定客户端请求的分配,根据实现机制的不同,可能包含直接路由模式、NAT模拟及隧道模式等多种工作模式,下面我们以NAT模式来给大家简单介绍一下四层负载均衡技术的基本原理。

客户端将请求发送给服务器群前端的负载均衡设备,负载均衡设备上的负载均衡服务接收到客户端请求,通过调度算法,选择真实服务器,再通过网络地址转换,用真实服务器地址重写请求报文的目标地址后,将请求发送给选定的真实服务器;真实服务器的响应报文通过负载均衡设备时,报文的源地址被还原为虚服务的VSIP,再返回给客户,完成整个负载调度过程。报文交互流程如图8-3-2所示:

图8-3-2 NAT四层负载均衡原理图

NAT方式服务器负载均衡报文交互流程说明:

(1) 图中CIP1和CIP2分别为客户端1和客户端2的IP地址,LB为负载均衡服务器,SIP1和SIP2分别为为真实服务器1与真实服务器2的IP地址。

(2) 客户端1发送服务请求报文,源IP为CIP1、目的IP为VIP。

(3) LB接收到请求报文后,借助调度算法计算出应该将请求分发给真实服务器1。

(4) LB使用DNAT技术分发报文,源IP保持不变,还是CIP1、目的IP更改为真实服务器IP,即图中的SIP1。

(5) 真实服务器1接收并处理请求报文,返回响应报文,这是报文源IP为SIP1、目的IP为CIP1。

(6) LB接收响应报文,转换源IP后转发,源IP更改为VIP、目的IP保持不变,即CIP1。

(7) 这样,负载均衡就实现到客户端和真实服务器的完整数据交换。

8.3.3 HTTP协议

HTTP是一个属于网站应用中客户端和服务器之间的通讯协议,它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展。目前在WWW中使用的是HTTP/1.0的第6版。

HTTP协议的主要特点可概括如下:

1.工作在客户/服务器模式。

2.简单快速:客户向服务器请求服务时,通过传送请求方法和路径来定位请求的资源。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器交互类型的不同。

3.灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由HTTP协议的特定域进行标记。

HTTP URL是HTTP网络资源定位的简写,客户端通过HTTP URL定位的格式如下:

http://主机名[":"TCP端口][/资源路径]

http表示表示客户端和服务器之间通过HTTP协议进行交互;主机名表示提供资源的服务器,可以使合法的Internet域名或IP地址;端口指定一个传输层端口,默认为80;绝对路径表示请求的资源在服务器上的相对路径,默认值通过Web服务器的设置来决定。例如:我们经常访问的网址 http://www.qq.com/ 就是一个合法的HTTP URL。

HTTP协议分为请求和响应两种类型,分别用于客户端和服务端,其中http请求由请求行、请求头、请求正文三部分组成,其中请求行主要用来申明请求的资源及使用的协议版本,请求头来申明对请求的属性,请求正文表示提交给服务器的数据,其中请求行的格式为Method URI HTTP Version,请求行的结束以换行回车作为标志,其中Method 表示对资源数据的操作方法,常用的方法为GET、POST、HEAD PUT、CONNETC、DELETE,URI为HTTP URL中的资源路径,version为版本号,现在主流的版本号为1.0。

请求头有多个字段组成,每个域的格式为字段名“: ”请求值组成,字段名大小写无关。请求头可以有多个这样的语法,每个语法之间通过换行回车符号作为间隔,请求头的结束通过连续的两个换行回车进行标识,常用的字段名及含义如下。

Accept:用于指定客户端接受哪些类型的信息。

Accept-Encoding:用于指定可接受的内容编码。

Accept-Charset:用于指定客户端接受的字符集。

Accept-Language:用于指定一种自然语言。

Host:用于指定被请求资源的主机,同一服务器可以通过不同的Host来实现虚拟Web站点的功能。

User-Agent:主要用于标识访问网站资源的客户端软件。

Cookie:用于传递服务器服务器分配给客户端的隐私数据,客户端用来向服务器表明身份或状态。

Content-Type:用于指定客户端上传数据的数据类型。

Content-Language:用于指定客户端上传数据的自然语言

Content-Length:用于指定客户端上传数据的长度。

HTTP响应由响应行、响应头和响应数据组成,其中响应行的格式为“HTTP” Version“ ”Status-Code“空格”Reason-Phrase ,请求行的结束标志位换行回车,其中:Version为协议版本号,主流的为1.0,Status-Code为一个整数值,表示请求的状态,Reason-Phrase为可读字符串,用于对Status-Code的简短描述,主要的Status-Code及含义包括。

1xx:指示信息,表示请求已接收,继续处理。

2xx:成功,表示请求已被成功接收、理解、接受。

3xx:重定向,要完成请求必须进行更进一步的操作。

4xx:客户端错误,请求有语法错误或请求无法实现。

5xx:服务器端错误,服务器未能实现合法的请求。

响应头的语法格式和请求头一样,差别仅仅是支持的字段名不同,响应头支持的常见字段名及含义包括。

Location:用于重定向接受者到一个新的位置。

Server:包含了服务器用来处理请求的软件信息。

Content-Encoding:用作媒体类型的修饰符,指示被应用到实体正文的附加内容的编码,因而获得Content-Type报头域中所引用的媒体类型,必须采用相应的解码机制。

Content-Language:描述了资源所用的自然语言。

Content-Length:用于指明实体正文的长度。

Cache-Control:用于指定缓存指令,

Content-Type:指明发送给接收者的实体正文的媒体类型。

Last-Modified:用于指示资源的最后修改日期和时间。

Expires:给出响应过期的日期和时间。

Set-Cookie:用于服务器向客户端设置隐私数据。

8.3.4 七层负载均衡技术

七层负载均衡和四层负载均衡相比,只是进行负载均衡的依据不同,而选择确定的实服务器后,所做的处理基本相同,下面以HTTP应用的负载均衡为例来说明。

由于在TCP握手阶段,无法获得HTTP协议真正的请求内容,因此也就无法将客户的TCP握手报文直接转发给服务器, 必须由负载均衡设备先和客户完成TCP握手,等收到足够的七层内容后,再选择服务器,由负载均衡设备和所选服务器建立TCP连接。

七层负载均衡组网和四层负载均衡组网有一个显著的区别:四层负载均衡每个虚服务对应一个实服务组,实服务组内的所有实服务器提供相同的服务;七层负载均衡每个虚服务对应多个实服务组,每组实服务器提供相同的服务。根据报文内容选择对应的实服务组,然后根据实服务组调度算法选择某一个实服务器。图8-3-3是一个基于七层负载均衡技术的客户端和服务器的交互过程。

图8-3-3 HTTP七层负载均衡部署构架

七层负载均衡报文交互流程说明:

(1) 图中CIP1为客户端1的IP地址,SIP1和SIP2为真实服务器1 真实服务器2的IP地址,两台服务器共同拥有虚拟一个虚拟IP,即图中的VIP,LB为负载均衡设备。

(2) 客户端和LB建立TCP连接,源IP地址为CIP1,目的IP为VIP,即图中步骤⑴。

(3) 客户端发送HTTP请求,LB设备分析报文,根据调度算法选择实服务器,假设选中真实服务器1提供服务,即图中步骤⑵。

(4) LB和真实服务器1,即SIP1建立TCP连接,即图中步骤⑶。

(5) LB向真实服务器发送HTTP请求,即图中步骤⑷。

(6) 真实服务器向LB响应数据,即图中步骤⑸。

(7) LB向客户端返回服务器响应数据,即图中步骤⑹。

(8) 图中步骤⑺-⑾为下一次请求的均衡处理,和真实服务器SIP2的数据交换类似图中步骤⑶-⑸。

8.3.5 Linux LVS技术

1.LVS

LVS,是Linux虚拟服务器(Linux Virtual Server)的简称是一个由章文嵩博士发起的自由软件项目,用于实现服务器的负载均衡。LVS组件由用户空间的ipvsadm和内核空间的ip_vs模块组成,ipvsadm用来定义规则,ip_vs模块利用ipvsadm定义的规则进行负载的分配,LVS已经是 Linux标准内核的一部分,在各种Linux版本的官方发行版本中,都带有LVS组件,可以直接使用LVS组件提供的各种负载均衡功能。

通过LVS提供的负载均衡技术,可以实现一个高性能、高可用的服务器群集,它具有良好可靠性、可扩展性和可操作性。从而以低廉的成本实现最优的服务性能。LVS的主要优势有以下几个方面。

(1) 高并发连接:LVS工作在Linux内核网络层,直接对报文进行处理,而不需要在用户空间和内核空间之间复制数据,有超强的承载能力和并发处理能力,单台LVS负载均衡器,即可支持十万级别的并发连接。

(2) 稳定性强:LVS仅仅在传输层上进行负载分配,不涉及到传输层上纠错、超时处理,因此软件代码简单、高效,这个特点也决定了它在负载均衡软件里的性能最强、稳定性最好。对内存和CPU资源消耗都很低。

(3) 成本低廉:硬件负载均衡器少则十几万,多则几十万上百万,LVS只需一台服务器和就能免费部署使用,性价比极高。

(4) 配置简单:LVS配置非常简单,仅需几行命令即可完成配置,也可写成脚本进行管理。

(5) 调度算法多样:支持多种调度算法,可根据业务场景灵活使用。

(6) 支持多种工作模型:可根据业务场景,使用不同的工作模式来解决生产环境请求处理问题。

(7) 应用范围广:它几乎可以对所有应用做负载均衡,包括但不限于HTTP、数据库、DNS、FTP服务等。

下面对LVS的技术原理及工作模式做一个简单的介绍。

2. Linux netfilter架构原理

LVS的实现是基于Linux netfilter构架来实现的,具体netfilter的构架详细见Linux相关章节的内容。

3. LVS的实现原理

LVS的实现是基于Linux netfilter构架来实现的,Linux ip_vs模块通过挂载在netfilter钩子上,对报文进行处理,其处理逻辑如图8-3-4所示:

图8-3-4 LVS处理逻辑

其负载均衡处理逻辑如下:

(1) 当用户发起的请求,通过计算机网络传输后,被送到负载均衡服务器的网卡启动进行处理,网卡驱动处理后的流量进入到内核空间的IP协议栈进行处理,即图中步骤⑴。

(2) IP协议栈收到数据包以后,首先进入PreRoute链处理,如果PreRoute链有钩子挂载,则钩子程序对报文进行处理后进入下一步,如果没有,则直接进入下一步,即图中步骤⑵。

(3) IP协议栈进行路由判断,即根据IP报文的目的IP,判断是服务器的本地流量还是需要通过服务器进行转发的其他流量,如果是本地流量,则进入到Input链进行处理,,即图中步骤⑶,如果不是本地流量,则进入Forward链进行处理。

(4) ip_vs是工作在Input链上的,当用户请求报文到达Input链时,ip_vs会将用户请求和自己已定义好的集群配置进行比对,如果用户请求的目的IP及目的端口就是定义的集群服务,那么此时ip_vs模块会根据配置的工作模式,对报文进行修改,并将新的数据包发往PostRoute链进行处理,否则交给上层协议处理,即图中步骤⑷。

(5) PostRoute链根据挂载的钩子程序对IP报文进行再次处理,如果没有钩子程序,则网卡直接进行发送,如果有钩子函数,则钩子函数处理后,通过网卡进行发送,即图中步骤⑸。

(6) 最终通过LVS负载均衡服务分派的流量被网络传送到某个真实服务器上,真实服务器的响应流量,根据工作模式的不同,即可以直接返回给客户端,也可能需要通过LVS负载均衡服务器进行报文的修改后,再次转发给客户端,即图中步骤⑹。

4. LVS的工作模式

直接路由模式的处理逻辑如图8-3-5所示。

图8-3-5 LVS直接路由模式原理

(1) 图中MC开头的表示MAC地址,IP开头的表示IP地址 ,符号|为分隔符,每个步骤中,其中->左边表示源头MAC和源IP,右边表示目的MAC和目的IP,如果没有MAC地址部分,就表示该报文可跨网段传输,MAC地址会随时发生变化,在后面的正文中,也使用本规则表示。

(2) 图中的IPC1和MCC1分别代表客户端1的IP地址和MAC地址,MCLB即负载均衡的MAC地址,IPS1、IPS2分别代表真实服务器1和真实服务器2的IP地址,MCS1和MCS2分别代表真实服务器1和真实服务器2的MAC地址,LB代表LVS,VIP为两台服务器共同拥有的虚拟IP地址

(3) 首先客户端向VIP发送请求,源IP为客户端1的IP地址IPC1,目的地址为VIP,为图中的第⑴步。

(4) LB比对数据包请求的服务是否为集群服务,若是,会根据负载均衡策略选择一个真实服务器,假设选择的是服务器1,LB将原始报文的源头MAC地址修改为MCLB,目的MAC修改为服务器1的MAC地址,即MCS1,从而将请求发送到真实服务器1,对于会话的初始报文,处理后会在会话表中增加条目,如果非会话的初始报文,LB会根据会话表决定真实服务器,即图中的第⑵步。

(5) 真实服务器响应客户端请求,由于请求报文传输过程中,源目的IP地址及上层协议都没有发生变化,因此返回流量可以不需要通过负载均衡设备LB,返回报文的目的IP地址为IPC1,源IP地址为VIP,根据路由情况决定将响应报文交给网络中的下一跳处理。即图中的第⑶步。

(6) 通过网络中的传播,客户端收到真实服务器的响应,即图中的第⑷步。

(7) 根据上面的步骤可以看到,不管是LB还是真实服务器上都需要配置虚拟IP地址VIP。

(8) 由于负载均衡设备传递给多个真实服务器的流量是通过MAC来区分的,因此他们必须在同一个二层交换网络中。

隧道模式的处理逻辑如图8-3-6所示。

图8-3-6 LVS隧道模式处理逻辑

(1) 客户端发起请求,此时报文的源IP为IPC1,目标IP为VIP ,即图中步骤⑴。

(2) 负载均衡设备收到报文后,比对数据包请求的服务是否为集群服务,若是,确定了提供服务器的真实服务器,假设还是选择真实服务器1,然后将用户请求IP报文封装到新的IPIP隧道报文中,隧道协议报文IP头中源IP为IPLB,目标IP为IPS1,然后通过网络发送出去,即图中步骤⑵。

(3) 网络通过隧道协议IP头的目的地址进行流量转发,最后送到真实服务1中,真实服务器1收到报文,首先检查外部头的目的IP地址,看是否自己的,如果是,再进行IP协议字段的检查,发现上层协议为IPIP隧道协议,这时真实服务器1检查自己是否配置了匹配的IPIP隧道接口,是就进一步处理,不是,就丢弃。

(4) 通过剥离IPIP协议头后,真实服务最终收到的IP报文为客户端的原始请求报文,这样真实服务器也需要配置VIP,才能接受客户端的请求,随后处理用户请求,构建响应报文,并根据自己的网络设置,将响应数据包通过网络发送给客户端,后面的步骤和直连模式一致。

(5) 从上面的工作过程来看,真实服务器和LB之间不需要二层网络互连,LB和真实服务器上都需要配置虚拟IP地址,即VIP。真实服务器的返回流量不需要通过LB。

NAT模式的处理逻辑如图8-3-7所示。

图8-3-7 LVS NAT模式处理逻辑

(1) 客户端向VIP发起请求,请求的源IP地址为IPC1,目的IP地址为VIP,通过网络的传递,此时请求的数据报文会转交给LB,即图中步骤⑴。

(2) LB比对数据包请求的服务是否为集群服务,若是,通过负载均衡算法选择真实服务器,假设选择真实服务器1,这样修改数据包的目标IP地址为真实服务器1的IP,即IPS1,然后发送到网络中,即图中步骤⑵。

(3) 真实服务器接收到报文后,比对发现目标IP为自己的IP,接受报文并构建响应报文给客户端,此时报文的源IP为IPS1,目标IP为IPC1。因此真实服务器看到的会话五元组信息和客户端看到的会话五元组信息是不匹配的,必须进行转换,而转换的逻辑只有LB知晓,所以网络中必须通过特殊配置,让真实服务器的返回流量通过负载均衡设备返,即图中步骤⑶。

(4) 负载均衡设备收到服务器响应后,此时会根据负载均衡的配置将源IP地址修改为虚拟IP地址,即VIP,然后将报文通过网络传递给客户端,即图中步骤⑷。 此时报文的源IP为VIP,目标IP为IPC1,和客户端发出的会话请求的五元组匹配。

5. 不同模式的优缺点

直接路由模式优缺点:

(1) 直接路由模式通过修改IP报文的目的MAC地址,从而将客户机流量交给指定的真实服务器处理,LVS对报文的处理开销小。

(2) 由于真实服务器配置有虚拟IP地址,因此能够接受LVS转发过来的客户端请求,同时,由于IP报文通过LVS服务器后没有任何变化,因此,真实服务器的返回流量可以直接返回给客户机,而不需要通过LVS服务器,可提高LVS的网络处理性能。

(3) 由于LVS服务器是通过目的MAC的修改来把流量传递给真实服务器的,因此,大多数情况下,需要将真实服务器和LVS服务器部署在同一网段下,从而限制了服务器的部署位置。

(4) LVS服务器对真实服务的可用性探测,大多数情况下,只能通过服务器的真实IP进行探测,如果服务器出现忘记配置虚拟IP的情况下,将导致真实服务器无法接受用户请求而LVS服务器不能发现的情况,从而引起客户端的失败。

隧道模式的优缺点:

(1) 隧道通过将客户端请求的IP报文,通过LB上进行IPIP隧道协议封装后发送到网络中,外部网络通过IPIP隧道协议的IP头进行流量转发,最终将流量发送到真实服务器上,由于IPIP协议封装引入了新的开销,因此报文的处理复杂度及网络带宽等开销都有一定的增加。

(2) 真实服务器通过IPIP协议的解封装,获取到内部的IP报文,而真实服务器上也配置有虚拟IP,故能够接受客户端的请求,这样客户端的真实请求通过LVS并未发生变化,服务器可以直接返回流量给客户端,从而降低LVS服务器的开销,提高网络性能。

(3) 由于客户端的请求通过IPIP协议进行了再次封装,因此LVS服务器和真实服务器的部署没有任何限制,只要IP网络能通,都可以实现负载均衡。

(4) LVS探测真实服务器服务可用性方面和直接路由模式一样,都存在只能通过真实IP探测而不能避免虚拟IP配置错误引起的网络故障。

NAT模式的优缺点:

(1) NAT模式通过修改IP报文的目的IP地址,从而将客户机流量交给指定的真实服务器处理,LVS对报文的处理开销小。

(2) 由于真实服务器接收的请求目的IP和客户端请求的目的IP不一致,因此真实服务器不能将响应直接返回给客户端,而需要将流量通过LVS转发,LVS将返回包的源地址修改为虚拟IP后才能返回给客户端,这样,由于双向流量都需要通过LVS进行处理,LVS的最大并发处理能力将下降。

(3) 由于LVS服务器是通过目的IP的修改来把流量传递给真实服务器的,LVS和真实服务器的部署不受部署位置的限制,主要网络中IP可达即可。

(4) LVS服务器对真实服务的可用性探测是通过服务器的真实IP进行探测,而真实服务器接收客户端的请求也是通过真实IP进行处理的,因此不存在隧道模式和直接路由模式存在的IP配置错误的问题。

6. LVS的负载均衡调度算法

LVS常用的负载均衡算法包括两类:

(1) 固定调度算法,即调度器不会去判断后端服务器的繁忙与否,一如既往得将请求派发下去,主要的固定调度算法包括:RR、WRR、SH、DH。

(2) 动态调度算法,调度器会去判断后端服务器的繁忙程度,然后依据调度算法动态得派发请求,主要的动态调度算法:WLC、LC、LBLC、LBLCR、SED、NQ。

不同调度算法的逻辑如下:

(1) RR(round robin)轮询算法,这种算法是最简单的,就是按顺序将每个新请求调度到不同的服务器上,所有服务器都分配到请求后,进行下一次的循环,轮询算法假设所有的服务器处理请求的能力都是一样的,调度器会将所有的请求平均分配给每个真实服务器,不管后端 RS 配置和处理能力,非常均衡地分发下去。这个调度的缺点是,如果服务器性能容量差异较大或者不同请求的复杂度不同,可能导致服务器性能不均衡。

(2) WRR(weight round robin)加权轮询,这种算法比RR 的算法多了一个权重的概念,可以给 RS 设置权重,权重越高,那么分发的请求数越多,权重的取值范围 0~100。主要是对RR算法的一种优化和补充, LVS 会考虑每台服务器的性能,并给每台服务器添加要给权值,如果服务器A的权值为1,服务器B的权值为2,则调度到服务器B的请求会是服务器A的2倍。权值越高的服务器,处理的请求越多。

(3) SH(Source Hashing)源地址散列调度算法,即根据客户端请求的源IP地址计算一个Hash结果,并根据Hash结果将请求发给后端的同一个服务器,这种算法可设置两种不同标志,sh-fallback标记是后端服务器失效时,会重新分配到有效的服务器,sh-port标记作用是将源端口加入Hash运算中。

(4) DH(Destination Hashing)目的地址散列调度算法,即根据客户端请求目的IP地址计算一个Hash结果,并根据这个Hash结果将请求发送给后端的同一台服务器。

(5) LC(least-connection)最少连接数,这个算法会根据后端 RS 的连接数来决定把请求分发给谁,比如 RS1 连接数比 RS2 连接数少,那么请求就优先发给 RS1。

(6) WLC(weight least-connection)加权最少连接数,这个比最少连接数多了一个加权的概念,即在最少连接数的基础上加一个权重值,当连接数除以权重的值越小,越优先被分派新请求。

(7) LBLC(locality-based least-connection)基于局部性的最少连接调度算法,这是一种基于目的地址的调度算法,它将来自同一目的地址的请求分配给同一台RS,条件是如果这台服务器尚未满负荷,否则分配给连接数最小的RS,并以它为下一次分配的首先考虑。

(8) LBLCR(Locality-Based Least-Connection with Replication)基于局部最少复制连接调度算法,该算法与LBLC的主要区别在于这种算法将一个目的服务映射到一个后端服务器集合中,客户端请求将被分配到服务器集合中连接数最少的服务器,如果集合中所有服务器都过载,将会从集群中选择一个最少连接的服务器加入服务器集合,如果服务器集合在指定的时间内都没有修改,就将负载最重的服务器移除服务器集合,以避免高强度的复制。

(9) SED(Shortest Expected Delay)最短期望延迟调度,即sed计算结果最小的服务器,将分配到新的会话,sed的计算值为(服务器的当前连接+1)/服务器服务率,服务器服务率为固定设置的值。

(10) NQ(Never Queue)永不队列调度,该调度算法规则为,如果有空闲服务器,就将新请求分配给空闲服务器,而不考虑谁最快,如果没有,谁最短期望延迟越小,就分配给谁。

8.3.6 负载均衡中的会话保持技术

在BS开发模式下,软件开发者使用HTTP协议作为客户端和服务器的通讯协议,通常情况下,HTTP请求都是短连接,即每个TCP请求获取一个数据,如果用户的一个事务需要在客户端和服务端之间传递多个数据,就需要建立多个TCP连接,在单服务器模式下,这不是问题,但是如果在客户端和服务器之间部署了负载均衡设备,很可能将同一事务的多个连接转交给不同的服务器进行处理,如果服务器之间没有会话信息的同步机制,会导致其他服务器无法识别用户身份,造成用户使用应用系统出现异常。会话保持就是这样一种机制,其保证将来自相同客户端的请求,转发至相同的后端服务器进行处理,也就消除不同服务状态数据的不同步问题。

常见的会话保持技术分为两类,四层会话保持和七层会话保持两种:

其中四层会话保持通常在客户端初次建立连接后,负载均衡服务器就将负载均衡服务器调度后的客户端和真实服务器的映射关系保存下来,这种映射关系的Key为客户端IP、服务器IP、协议及服务器端口,值为真实服务器地址,如果后续的连接匹配这些元素,就认为是同一客户的其他请求,负载服务器将把这些连接请求调度到同一服务器上,从而实现会话状态的一致性保证。

七层会话保持指负载均衡服务器根据客户端初次连接的应用层数据(如HTTP协议的Header数据、HTTP协议的Cookie数据、SSL协议的会话ID、SIP协议中的SIP ID等)结合目的服务器IP、目的服务器端口、协议类型数据作为Key,来记录特定客户端和服务器之间的映射关系,从本质上来说,这些应用层数据在客户端的事务连接中,绝大多数情况都会保持不变,因此可以用来识别唯一的客户端,从而在后续的连接中,将特定的客户端和服务器对应起来,确保客户端的状态数据的一致性。

8.4 服务器动态路由实现

当业务系统的并发请求超过单台负载均衡服务器处理能力的时候,就需要通过扩展更多的负载均衡服务器来满足业务的要求,最常用的方法就是通过等值多路径路由的方式,利用网络设备的多路径负载均衡能力,将客户端的请求分配给多台负载均衡服务器,这样就可以降低负载均衡服务器的性能压力,根据网络设备的不同,等值多路径负载均衡最大的并发转发路径为8、16及32路,因此,理论上可以做到32台负载均衡服务器组成一个负载均衡集群。

要通过网络设备实现负载均衡服务器的多路径负载均衡,就需要在负载均衡服务器上配置动态路由,通过将虚拟IP部署到每个负载均衡服务器上,并通过动态路由宣告出来,从而在网络设备上产生多条并行路由,从而实现网络上的负载均衡。

Linux服务器上最常用的路由软件是Quagga,Quagga原名是Zebra,是由一个日本开发团队编写的一个以GNU版权方式发布的软件。Quagga项目开始与1996年,当前版本是0.98.4版,可以使用Quagga将Linux机器打造成一台功能完备的路由器。

Quagga能够同时支持RIPv1、RIPv2、RIPng、OSPFv2、OSPFv3、BGP-4和 BGP-4+等诸多TCP/IP协议。其中:

(1) RIPv1、RIPv2、OSPFv2适用于IPv4的自治域系统内部网络路由协议。

(2) BGP-4是用于IPv4的自治域系统之间的外部网络路由协议。

(3) RIPng、OSPFv3、BGP-4+主要扩展对IPv6的支持。

Quagga的软件特征包括:

(1) 模块化设计:Quagga基于模块化方案的设计,即对每一个路由协议使用单独的守护进程。

(2) 运行速度快:因为使用了模块化的设计,使得Quagga的运行速度比一般的路由选择程序要快。

(3) 可靠性高:在所有软件模块都失败的情况下,路由器可以继续保持连接并且daemons也会继续运行。故障诊断不必在离线的状态下被诊断和更正。

(4) 支持IPv6:Quagga不仅支持IPv4,还支持IPv6。

Quagga运行时要运行多个守护进程,各个具体的守护进程及作用:

(1) zebra,守护进程用来更新内核的路由表及维护接口的配置。

(2) ripd,守护进程用来进行IPv4的RIP路由学习。

(3) ripngd,守护进程用来进行IPv4的RIP路由学习。

(4) ospfd,守护进程用来进行IPv4的OSPF路由学习。

(5) bgpd,守护进程用来进行BGP路由学习。

(6) ospf6d,守护进程用来进行IPv6的OSPF路由学习。

(7) isisd,守护进程用来进行ISIS路由学习。

8.5 Keepalived基本原理

Keepalived是Linux下一个轻量级别的高可用(High Availability,HA)解决方案,Keepalived主要是通过虚拟路由冗余来实现高可用功能,通过LVS结合Keepalived的监控检测及跟踪功能,实现服务器的负载均衡。

Keepalived在设计之初是基于LVS实现的负载均衡,其通过在LVS的基础上,扩展了专门用来监控集群系统中各个服务节点的模块,其根据TCP/IP参考模型的第三层、第四层及应用层检测每个服务节点的状态,如果某个服务器节点出现异常,或者工作出现故障,Keepalived检测发现后,会将出现故障的服务器节点从集群系统中剔除,这些工作全部是自动完成的,不需要人工干涉,从而在实现负载均衡的基础上,实现了服务器的高可用。

随后Keepalived在原来负载均衡的基础上,引入了VRRP(Virtual Router Redundancy Protocol,虚拟路由冗余协议)功能,VRRP协议开发初期是解决静态路由中的单点故障问题,通过VRRP可以缺省网关的选举和故障自动切换,从而实现网络不间断稳定运行,Keepalived软件通过引入该协议,实现了多个Keepalived组成一个高可用集群,从而实现了自身的高可用。

8.5.1 VRRP协议介绍

VRRP是一种容错协议,它保证当主机的下一跳路由器出现故障时,由另一台路由器来代替出现故障的路由器进行工作,从而保持网络通信的连续性和可靠性。

VRRP将局域网内的一组路由器划分在一起,形成一个VRRP备份组,它在功能上相当于一台虚拟路由器,使用虚拟路由器号进行标识。

虚拟路由器有自己的虚拟IP地址和虚拟MAC地址,它的外在表现形式和实际的物理路由器完全一样。局域网内的主机将虚拟路由器的IP地址设置为默认网关,通过虚拟路由器与外部网络进行通信。

虚拟路由器是工作在实际的物理路由器之上的。它由多个实际的路由器组成,包括一个Master路由器和多个Backup路由器。Master路由器正常工作时,局域网内的主机通过Master与外界通信。当Master路由器出现故障时,Backup路由器中的一台设备将成为新的Master路由器,接替转发报文的工作。

VRRP的工作过程为:

(1) 虚拟路由器中的路由器根据优先级选举出Master。Master路由器通过发送免费ARP报文,将自己的虚拟MAC地址通知给与它连接的设备或者主机,从而承担报文转发任务;

(2) Master路由器周期性发送VRRP报文,以公布其配置信息(优先级等)和工作状况;

(3) 如果Master路由器出现故障,虚拟路由器中的Backup路由器将根据优先级重新选举新的Master;

(4) 虚拟路由器状态切换时,Master路由器由一台设备切换为另外一台设备,新的Master路由器只是简单地发送一个携带虚拟路由器的MAC地址和虚拟IP地址信息的免费ARP报文,这样就可以更新与它连接的主机或设备中的ARP相关信息。网络中的主机感知不到Master路由器已经切换为另外一台设备。

(5) Backup路由器的优先级高于Master路由器时,由Backup路由器的工作方式(抢占方式和非抢占方式)决定是否重新选举Master。

VRRP具有如下优点:

(1) 简化网络管理。在具有多播或广播能力的局域网(如以太网)中,借助VRRP能在某台设备出现故障时仍然提供高可靠的缺省链路,有效避免单一链路发生故障后网络中断的问题,而无需修改动态路由协议、路由发现协议等配置信息,也无需修改主机的默认网关配置。

(2) 适应性强。VRRP报文封装在IP报文中,支持各种上层协议。

(3) 网络开销小。VRRP只定义了一种报文—VRRP通告报文,并且只有处于Master状态的路由器可以发送VRRP报文。

8.5.2 Keepalived架构

Keepalived架构如图8-5-1所示,从中我们可以看到,Keepalived的功能实现主要通过用户空间的功能结合内核模块来实现的。

图8-5-1 Keepalived构架图

内核空间包括:

(1) NETLINK模块,主要用于实现一些高级路由框架和一些相关参数的网络功能,接收用户空间中NETLINK反射器模块发来的各种网络请求并处理。

(2) IPVS模块,主要实现LVS负载分担功能。

用户空间层主要包含以下4个部分:

(1) 调度器及IP多路复用,是一个I/O复用分发调度器,它负载安排Keepalived所有内部的任务请求。

(2) 内存管理,是一个内存管理机制,这个框架提供了访问内存的一些通用方法。

(3) 控制面板,是Keepalived的控制版面,可以实现对配置文件编译和解析。

(4) 核心组件,Keepalived业务逻辑的实现。

核心组件主要包含以下4个部分:

(1) 看门狗,是计算机可靠领域中极为简单又非常有效的检测工具,Keepalived正是通过它监控Checkers和VRRP进程的。

(2) 健康检查,这是Keepalived最基础的功能,也是最主要的功能,可以实现对服务器运行状态检测和故障隔离。

(3) VRRP 协议栈,这是Keepalived后来引用的高可用特征,可以实现HA集群中失败切换功能。

(4) IPVS封装器,这是IPVS功能的一个实现,IPVS wrapper模块将可以设置好的IPVS规则发送的内核空间并且提供给IPVS模块,最终实现IPVS模块的负载功能。

(5) NETLINK反射器,用来实现高可用集群Failover时虚拟IP(VIP)的设置和切换。

8.6 HAProxy基本原理

HAProxy是一个开源负载均衡软件,其提供基于四层和七层的高可用性、负载均衡功能。HAProxy特别适用于那些负载特大的Web站点,并且提供会话保持或基础应用层数据的负载均衡处理逻辑,HAProxy在当前主流的硬件上,典型部署模式下可以支持数以万计的并发连接,HAProxy使用了一种事件驱动, 单一进程的软件构架,这种构架采用事件驱动模型较好的解决了多线程模型的内存限制、系统调度器限制以及锁限制,因此能够支持非常大的并发连接数。HAProxy作为一个专业的负载均衡软件,它的显著优点如下:

(1) 可靠性和稳定性非常好,可以与硬件级的F5负载均衡设备相媲美。

(2) 最高可以同时维护40000~50000个并发连接,单位时间内处理的最大请求数为20000个,最大数据处理能力可达10Gbps。

(3) 支持多于8种负载均衡算法,同时也支持Session保持。

(4) 支持虚拟主机功能,这样实现Web负载均衡更加灵活。

(5) 从HAProxy1.3版本后开始支持连接拒绝、全透明代理等功能。

(6) HAProxy拥有一个功能强大的服务器状态监控页面。

(7) HAProxy拥有功能强大的访问控制(ACL)功能。

HAProxy软件从逻辑架构上来说,主要分为前端(Front End)、后台(Back End)及负载均衡三个部分组成,其中前端用来接收客户端的连接,并对客户端的请求数据进行提出分析,后台的主要功能用于真实服务器的连接,并对服务器的响应数据进行提取分析,其中负载均衡实现请求分担、连接保持等主要的负载均衡能力,典型的HAProxy部署逻辑如图8-6-1所示。

图8-6-1 HAProxy典型部署结构

HAProxy 配置文件根据功能和用途的不同,主要有五个部分组成,具体如下:

(1) global

用来设定全局配置参数,主要用于定义HAProxy进程管理安全及性能相关的参数。

(2) defaults

默认参数的配置。在此部分设置的参数值,默认会自动被frontend、backend 和 listen 引用,如果某些参数属于公用配置,只需在 defaults 部分配置一次即可。而如果在 frontend、backend 和 listen 中也配置了与 defaults 部分一样的参数,那么defaults 部分参数对应的值会被自动覆盖。

(3) frontend

此部分配置主要用于设置用户请求的处理及参数,frontend 可以根据 ACL策略直接指定不同的请求要使用的后端服务。

(4) backend

此部分用于设置后端服务集群的配置类似于 LVS 中的real server 配置。

(5) listen

此部分配置实际上就是end和 backend 配置的结合,主要用在Proxy1.3 版本之前,为了保持兼容性,HAProxy 新的版本保留了这种配置方式,在 目前的HAProxy版本中,两种配置方式任选其一即可,但是为了后向兼容,建议使用独立的frontend 及backend方式进行配置。

项目实施

某电子商务公司,随着用户的增加及平均交易量的快速增长,其网站服务器的访问量越来越大,单台服务器与单个负载均衡设备的性能容量已经不能满足负载的需求,对此,技术人员准备采用网络设备的等值多路径负载均衡方式来实现负载均衡设备的平行扩展,通过软件负载均衡来实现服务器的负载分担,通过前期调研,技术团队决定通过Quagga软件的动态路由功能实现负载均衡设备的平行扩展及负载分担,通过Keepalived负载均衡软件来实现无差别服务集群的负载分担,通过HAProxy软件实现具有WEB动静分离的服务器负载分担。

需要完成的任务:

  • Quagga动态路由软件的安装及部署。
  • Keepalived的安装及部署。
  • HAProxy的安装及部署。

8.7 服务器负载均衡的部署

8.7.1 等值路由负载均衡部署

本次实验利用开源路由软件Quagga实现服务器与网络设备之间的动态路由协议,通过在多台服务器上配置ospf动态路由及共享虚拟IP,让网络设备上存在多条等值路由,从而让多台服务器使用单个VIP为客户端提供服务,本次实验的网络结构如图8-7-1所示,图中Server1模拟路由器设备,Server2和Server3模拟部署业务的真实服务器,真实服务器都配置虚拟IP,即图中的IP地址192.168.20.20/32,实现同时为用户提供服务。

图8-7-1 等值负载均衡实验拓扑

1. Quagga软件的安装

以下我们以Centos 7来讲解Quagga的安装,安装方式使用yum工具进行安装。

分别登录到3台服务器上,执行如下Shell命令安装Quagga软件。

yum install -y quagga.x86_64

Quagga的各个组件的运行配置需要通过telnet软件来管理,也可以通过软件包自带的vtysh程序进行管理,在3台服务器上分别安装telnet软件,执行如下Shell命令。

yum install -y telnet.x86_64

2. Quagga软件的初始化配置

Quagga软件的各个组件的配置文件保存在/etc/quagga目录下,配置文件名格式为“组件名”.conf,各个组件要能够使用Telnet进行正常的运行和管理,首先要进行密码的配置,配置方式使用vim编辑器,对zebra服务组件的配置文件进行修改,下面的操作在3台服务器上同时进行。

使用vi编辑器修改配置文件。

vi /etc/quagga/zebra.conf

进入程序界面后,在文件中增加如下内容:

hostname <主机名>
password <密码>

修改完成后,退出程序,并保存修改。

使用如下命令修改文件的拥有者属性。

chown quagga:quagga  /etc/quagga/zebra.conf

使用如下命令,初始化ospf的配置文件。

cd /etc/quagga
touch ospfd.conf
chown quagga:quagga ospfd.conf

启动zebra及ospfd服务,并设置为开机自启动,执行如下Shell命令。

systemctl start zebra.service
systemctl enable zebra.service
systemctl start ospfd.service
systemctl enable ospfd.service

启动各个组件服务后,就可以通过telnet进行管理,各个组件默认的监听地址为127.0.0.1,每个组件的监听端口如下:

zebra 2601/tcp # zebra vty

ripd 2602/tcp # RIPd vty

ripngd 2603/tcp # RIPngd vty

ospfd 2604/tcp # OSPFd vty

bgpd 2605/tcp # BGPd vty

ospf6d 2606/tcp # OSPF6d vty

isisd 2608/tcp # ISISd vty

除了可以通过Telnet进行管理外,Quagga软件还提供一个专用的命令行程序vtysh,提供Quagga软件的统一配置功能。

3. 服务器动态路由配置

(1) Server1配置

登录到Server1服务上,执行命令。

vtysh

下面为软件的提示及用户的配置,其中斜体字为用户输入。

Hello, this is Quagga (version 0.99.22.4).
Copyright 1996-2005 Kunihiro Ishiguro, et al.
localhost.localdomain# *configure terminal* 
localhost.localdomain(config)# *router ospf* 
localhost.localdomain(config-router)# n*etwork 192.168.126.0/24 area 0*
localhost.localdomain(config-router)# *end*
localhost.localdomain# *write memory*  
Building Configuration...
Configuration saved to /etc/quagga/zebra.conf
Configuration saved to /etc/quagga/ospfd.conf
[OK]
localhost.localdomain# *exit

(2) Server2配置

登录到Server2服务上,执行命令。

vtysh

下面为软件的提示及用户的配置,其中斜体字为用户输入。

Hello, this is Quagga (version 0.99.22.4).
Copyright 1996-2005 Kunihiro Ishiguro, et al.
localhost.localdomain# *configure terminal*  
localhost.localdomain(config)# *interface lo*
localhost.localdomain(config-if)# *ip address 192.168.20.20/32*
localhost.localdomain(config-if)# *exit* 
localhost.localdomain(config)# *router ospf* 
localhost.localdomain(config-router)# *network 192.168.126.0/24 area 0*
localhost.localdomain(config-router)# *network 192.168.20.20/32 area 0*
localhost.localdomain(config-router)# *end*
localhost.localdomain# *write memory* 
Building Configuration...
Configuration saved to /etc/quagga/zebra.conf
Configuration saved to /etc/quagga/ospfd.conf
[OK]
localhost.localdomain# *exit

(3) Server3配置

Server3的配置和Server2完全相同,这里就不讲解了。

4. 运行状态检查

登录到Server1服务器上,执行如下命令。

vtysh

执行下面内容的相关命令,检查ospf协议的状态,下面斜体字为用户输入内容。

localhost.localdomain# *show ip route* 
localhost.localdomain# *show ip ospf neighbor* 
localhost.localdomain# *show ip ospf database*
localhost.localdomain# *show ip ospf database router* 192.168.20.20

8.7.2 Keepalived负载均衡部署

本次实验使用Keepalived进行服务器负载均衡集群的部署,Keepalived和真实服务器之间采用隧道模式,其中Keepalived提供负载均衡及VRRP虚拟地址功能,RealServer1和RealServer2为真实服务器,提供网站的内容,实验的网络结构如图8-7-2所示。

图8-7-2 Keepalived负载均衡拓扑

1. Keepalived服务器部署

登录到Keepalived服务上,执行如下命令安装Keepalived及ipvsadm软件包:

yum install -y keepalived
yum install -y ipvsadm

使用vi编辑器,编辑文件/etc/keepalived/keepalived.conf,修改或增加的配置内容如下:

! Configuration File for keepalived
global_defs {
  notification_email {
   acassen@firewall.loc
   failover@firewall.loc
   sysadmin@firewall.loc
  }
  router_id LVS_DEVEL
  vrrp_skip_check_adv_addr
  vrrp_garp_interval 0
  vrrp_gna_interval 0
}
vrrp_instance VI_1 {
  state MASTER
  interface ens32
  virtual_router_id 51
  priority 100
  advert_int 1
  authentication {
    auth_type PASS
    auth_pass Cisc0123
  }
  virtual_ipaddress {
    192.168.126.222
  }
}
virtual_server 192.168.126.222 80 {
  delay_loop 6
  lb_algo rr
  lb_kind TUN
  persistence_timeout 50
  protocol TCP
  real_server 192.168.126.244 80 {
    weight 1
    HTTP_GET {
      url {
       path /
      }
      connect_timeout 3
      nb_get_retry 3
      delay_before_retry 3
    }
  }
   real_server 192.168.126.245 80 {
    weight 1
    HTTP_GET {
      url {
       path /
      }
      connect_timeout 3
      nb_get_retry 3
      delay_before_retry 3
    }
  }
}

2. RealServer服务部署

下面步骤在RealServer1和RealServer2上分别执行。

通过如下命令新建文件/etc/sysconfig/network- scripts/ifcfg-tun0。

touch /etc/sysconfig/network- scripts/ifcfg-tun0

使用vi编辑器编辑/etc/sysconfig/network- scripts/ifcfg-tun0,内容如下:

DEVICE=tun0
BOOTPROTO=none
ONBOOT=yes
TYPE=IPIP
PEER_OUTER_IPADDR=192.168.126.240
MY_INNER_IPADDR=192.168.126.222

执行如下命令,让配置生效。

systemctl restart network

使用vi编辑器修改文件/etc/sysctl.conf,增加如下内容,避免真实服务器响应VIP的ARP请求以及避免真实服务器做反向路径安全检查。

net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.ens32.arp_ignore = 1
net.ipv4.conf.tun0.rp_filter = 0
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0

执行如下命令,让配置生效。

sysctl -q -p /etc/sysctl.conf

执行如下命令,安装Apache http服务器。

yum install -y httpd.x86_64

使用vi编辑器新建一个文件/var/www/html/index.html,根据真实服务器的不同,内容有所不同,RealServer1内容如下:

<html>
<head>
<title>我的第一个 HTML 页面</title>
</head>
<body>
<p>This is First RealServer。</p>
<p>这是第一个真实服务器的网页内容</p>
</body>
</html>

RealServer2的内容如下:

<html>
<head>
<title>我的第一个 HTML 页面</title>
</head>
<body>
<p>This is Second RealServer。</p>
<p>这是第二个真实服务器的网页内容</p>
</body>
</html>

3. 负载均衡检验

在客户端上打开浏览器,访问http://192.168.126.222/,通过页面内容可以观察到客户端连接到那台真实服务器上,多次刷新页面,可以看到显示的内容保持不变,这是LVS的会话保持机制在起作用。

登录到提供内容的真实服务器上,通过如下命令关闭HTTP服务。

systemctl stop httpd.serice

稍微等待一段时间,再次通过浏览器访问http://192.168.126.222/,可以看到页面内容已经切换为另外一台服务器的内容。

登录到Keepalived服务器上,执行如下命令,可以检查LVS的负载均衡设置。

ipvsadm -L -n

通过如下命令,可以检查当前的客户端会话及状态。

ipvsadm -L -c -n

8.7.3 HAProxy负载均衡部署

本次实验使用HAProxy进行服务器负载均衡集群的部署,真实服务器上分别部署Apache Web服务器和Tomcat中间件系统,其中Apache提供静态内容,动态内容由Tomcat的JSP动态产生,实验的网络结构如图8-7-3所示。

图8-7-3 HAProxy负载均衡部署

图中RealServer1和RealServer2为真实服务器,提供网站的具体内容,每个服务器上都运行着Apache Web服务软件和Tomcat中间件系统。

1. HAProxy部署

登录到HAProxy服务器上,执行如下命令安装HAProxy软件。

yum install -y haproxy.x86_64

使用vi编辑器,修改/etc/haproxy/haproxy.cfg文件,修改的部分如下:

frontend main
  bind *:80
  acl url_static path_end -i .jpg .gif .png .css .js .html /
  use_backend tomcat if ! url_static
  default_backend  apache
backend apache
  balance   roundrobin
  http-check expect status 200
  server   apache1 192.168.126.244:80 check
  server   apache2 192.168.126.245:80 check
backend tomcat
  balance   roundrobin
  option tcp-check
  tcp-check connect
  cookie JSESSIONID prefix indirect
  server tomcat1 192.168.126.244:8080 cookie tomcat1 check
  server tomcat2 192.168.126.245:8080 cookie tomcat2 check

使用如下命令启动HAProxy服务。

systemctl restart haproxy.service

2. 真实服务部署

分别登录到真实服务器RealServer1或RealServer2上,执行如下命令安装Apache Web软件。

yum install -y httpd.x86_64

登陆到RealServer1上,使用vi编辑器,创建文件/var/www/html/index.html,内容如下:

<html>
<head>
<title>我的第一个 HTML 页面</title>
</head>
<body>
<p>这是第一个真实服务器的静态内容</p>
<iframe src="/sample/index.jsp" frameborder="0"></iframe>
</body>
</html>

登陆到RealServer12,使用vi编辑器,创建文件/var/www/html/index.html,内容如下:

<html>
<head>
<title>我的第一个 HTML 页面</title>
</head>
<body>
<p>这是第二个真实服务器的静态网页内容</p>
<iframe src="/sample/index.jsp" frameborder="0"></iframe>
</body>
</html>

分别登陆到RealServer1和RealServer2上,使用如下命令,启动httpd服务。

systemctl restart httpd.service

分别登陆到RealServer1和RealServer2上,使用如下命令,安装Tomcat中间件,并初始化网站配置。

yum install -y tomcat.noarch
mkdir /var/lib/tomcat/webapps/sample
cd /var/lib/tomcat/webapps/sample
mkdir META-INF
mkdir WEB-INF

分别登陆到RealServer1和RealServer2上,使用vi编辑器,创建文件/varlib/tomcat/webapps/sample/index.jsp,文件内容如下:

<html>
<head>
   <title>Hello World - test the J2EE SDK installation
   </title>
</head>
<body>
<%@ page import="java.io.BufferedReader,java.io.InputStreamReader,java.util.*, java.text.SimpleDateFormat" %>
<%
 Process p = Runtime.getRuntime().exec("hostname");
 BufferedReader rbuffer = new BufferedReader(new InputStreamReader(p.getInputStream()));
 String line = null;
 StringBuilder BString = new StringBuilder();
 while((line = rbuffer.readLine()) != null) {
    BString.append(line + "\n");
 }
 SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
 String current=dateformat.format(new Date());
 %>
 <h1>Server Hostaname is: <%=BString.toString()%><h1>
 <h1>Current time is : <%=current%> <h2>
</body>

执行如下命令,启动tomcat脚本。

chown -R tomcat:tomcat /var/lib/tomcat/webapps/sample
systemctl start tomcat.service

3. 负载均衡效果验证

在客户端上打开浏览器,访问http://192.168.126.240/,可以观察网页的内容包含两个部分,一部分内容为包含“静态王亚茹内容”的行,这是由Apache WEB服务提供的,另外一部分为包含“Server Hostaname is”和“Current time is”的两行,这是Tomcat JSP页面产生的,多次刷新页面,可以看到第一部分的内容不停的在第一个服务器和第二个服务器之间切换,这表示每次刷新后,提供内容的服务器都会发生变化,这就是没有开启会话保持的效果,而第二部分的内容除了时间会随刷新而变化,字符串“Server Hostaname is:”后面的内容不会发生变化,这表示提供这部分内容的服务器没有发生变化,这是由于在HAProxy中对动态内容后台配置了会话保持,导致第第二部分的请求每次都是同一服务器提供的。

任意登录到RealServer1或RealServer2上,通过如下命令关闭HTTP服务。

systemctl stop httpd.serice

稍微等待一段时间,再次通过浏览器访问http://192.168.126.222/,可以看到页面内容静态部分已经固定为单个服务的内容了。

根据动态内容的指示,登录提供动态内容的服务器上,执行如下命令,停止Tomcat服务。

systemctl stop tomcat

稍微等待一段时间,可以看到页面内容的第二部分也发生变化。

本章小结

本章以电商网站的高可用及可扩展应用需求为引导,介绍了基础网络的多路径负载均衡、网络层负载均衡及七层负载均衡的原理,并通过开源软件Quagga、Keepalived、HAProxy的部署案例,让读者通过本章的学习,能够掌握负载均衡系统的设计、部署的基本技能,以应对企业用户或业务快速增长的需求。

本章习题

一、选择题

(1)LVS是基于Linux内核的那种技术实现的( )。

A. 软中断

B. tasklet

C.文件系统

D.netfilter

2.LVS那种模式要求服务器返回流量必须经过LVS( )。

A.直连路由模式

B. 隧道模式

C.NAT模式

D.都需要

3.下面哪种负载均衡技术,可以显示用户的就近接入( )。

A.基于DNS全局负载均衡技术

B.基于网络层的负载均衡技术

C.基于应用层的负载均衡技术

D.基于等值多路径的负载均衡技术

4.负载均衡中,会话保持技术的作用是( )。

A.提高性能

B.提高可用性

C.保持应用状态一致

D.没有用

5.Keepalived支持哪种负载均衡技术( )。

A.链路捆绑

B.等值多路径

C.DNS负载均衡

D.网络层负载均衡

6.下面那个命令可以用户LVS连接表的查看( )。

A.ipvsadm

B.yum

C.systemctl

D.vi

二、多项选择题

1.HAProxy支持那些负载均衡技术 ( )。

A.基于DNS的全局负载均衡技术

B.网络层负载均衡技术

C.七层负载均衡技术

D.等值多路径负载均衡技术

2.LVS哪种模式要求虚拟IP配置在真实服务器上( )。

A.隧道模式

B.直连路由模式

C.NAT模式

D.所有模式

三、判断题

1.基于DNS的负载均衡技术,能够实现基于每用户的接入点分配。

2.Quagga支持OSPF、BGP、RIP路由协议。

3.Keepalived支持基于应用层数据的会话保持技术。