1 什么是负载均衡
负载均衡(LB,Load Balance),是一种技术解决方案。用来在多个资源(一般是服务器)中分配负载,达到最优化资源使用,避免过载。
客户端的流量首先会到达负载均衡服务器,由负载均衡服务器通过一定的调度算法将流量分发到不同的应用服务器上面,同时负载均衡服务器也会对应用服务器做周期性的健康检查,当发现故障节点时便动态的将节点从应用服务器集群中剔除,以此来保证应用的高可用。
2 什么是高可用
高可用是 CAP 定理是分布式系统的基础,也是分布式系统的3 个指标:
Ø Consistency(一致性)
Ø Availability(可用性)
Ø Partition tolerance(分区容错性)
高可用(High Availability)是什么?高可用,简称 HA,是系统一种特征或者指标,通常是指,提供一定性能上的服务运行时间,高于平均正常时间段。反之,消除系统服务不可用的时间。
衡量系统是否满足高可用,就是当一台或者多台服务器宕机的时候,系统整体和服务依然正常可用。
负载均衡(Load Balance)是分布式系统架构设计中必须考虑的因素之一。一般通过负载均衡,冗余同一个服务实例的方式,解决分布式系统的大流量、高并发和高可用的问题。负载均衡核心关键:在于是否分配均匀。
3 OSI七层模型与TCP/IP四层模型
4 负载均衡的分类
4.1 按网络模型分层分类
1) 二层负载均衡(mac)
根据OSI模型分的二层负载,一般是用虚拟mac地址方式,外部对虚拟MAC地址请求,负载均衡接收后分配后端实际的MAC地址响应)
2) 三层负载均衡(ip)
一般采用虚拟IP地址方式,外部对虚拟的ip地址请求,负载均衡接收后分配后端实际的IP地址响应)
3) 四层负载均衡(tcp)
在三次负载均衡的基础上,用ip+port接收请求,再转发到对应的机器。
4) 七层负载均衡(http)
根据虚拟的url或IP,主机名接收请求,再转向相应的处理服务器。
4.2 最常见的四层和七层负载均衡
1)四层的负载均衡就是基于IP+端口的负载均衡:在三层负载均衡的基础上,通过发布三层的IP地址(VIP),然后加四层的端口号,来决定哪些流量需要做负载均衡。
对应的负载均衡器称为四层交换机(L4 switch),主要分析IP层及TCP/UDP层,实现四层负载均衡。此种负载均衡器不理解应用协议(如HTTP/FTP/MySQL等等)。
实现四层负载均衡的软件有:
1) F5:硬件负载均衡器,功能很好,但是成本很高。
2) lvs:重量级的四层负载软件
3) nginx:轻量级的四层负载软件,带缓存功能,正则表达式较灵活
4) haproxy:模拟四层转发,较灵活
2)七层的负载均衡就是基于虚拟的URL或主机IP的负载均衡
对应的负载均衡器称为七层交换机(L7 switch),除了支持四层负载均衡以外,还有分析应用层的信息,如HTTP协议URI或Cookie信息,实现七层负载均衡。此种负载均衡器能理解应用协议。
实现七层负载均衡的软件有:
1) haproxy:天生负载均衡技能,全面支持七层代理,会话保持,标记,路径转移;
2) nginx:只在http协议和mail协议上功能比较好,性能与haproxy差不多;
3) apache:功能较差
4) Mysql proxy:功能尚可。
总的来说,一般是lvs做4层负载;nginx做7层负载;haproxy比较灵活,4层和7层负载均衡都能做。
5 负载均衡方案
目前市面上最常见的负载均衡技术方案主要有三种:
1) 基于DNS负载均衡
2) 基于硬件负载均衡
3) 基于软件负载均衡
三种方案各有优劣,DNS负载均衡可以实现在地域上的流量均衡,硬件负载均衡主要用于大型服务器集群中的负载需求,而软件负载均衡大多是基于机器层面的流量均衡。在实际场景中,这三种是可以组合在一起使用。
负载均衡也分为服务端负载均衡和客户端负载均衡;客户端负载均衡见附录:12.4.1Spring Cloud Ribbon和12.4.2 Spring Cloud Feign。
5.1 DNS负载均衡
基于DNS来做负载均衡其实是一种最简单的实现方案,通过在DNS服务器上做一个简单配置即可。其原理就是当用户访问域名的时候,会先向DNS服务器去解析域名对应的IP地址,这个时候我们可以让DNS服务器根据不同地理位置的用户返回不同的IP。比如南方的用户就返回我们在广州业务服务器的IP,北方的用户来访问的话,我就返回北京业务服务器所在的IP。
在这个模式下,用户就相当于实现了按照「就近原则」将请求分流了,既减轻了单个集群的负载压力,也提升了用户的访问速度。使用DNS做负载均衡的方案,天然的优势就是配置简单,实现成本非常低,无需额外的开发和维护工作。
但是也有一个明显的缺点是:当配置修改后,生效不及时。这个是由于DNS的特性导致的,DNS一般会有多级缓存,所以当我们修改了DNS配置之后,由于缓存的原因,会导致IP变更不及时,从而影响负载均衡的效果。
另外,使用DNS做负载均衡的话,大多是基于地域或者干脆直接做IP轮询,没有更高级的路由策略,所以这也是DNS方案的局限所在。
5.2 硬负载均衡
硬件负载均衡就是用一个硬件一个基础网络设备,类似我们的交换机啊这样的硬件,来实现负载均衡。
硬件负载均衡解决方案是直接在服务器和外部网络间安装负载均衡设备,这种设备我们通常称之为负载均衡器,由于专门的设备完成网络请求转发的任务,独立于操作系统,整体性能高,负载均衡策略多样化,流量管理智能化。
因为这类设备一般用在大型互联网公司的流量入口最前端,以及政府、国企等不缺钱企业会去使用。一般的中小公司是不舍得用的。采用 F5 这类硬件做负载均衡的话,主要就是省心省事,买一台就搞定,性能强大,一般的业务不在话下。而且在负载均衡的算法方面还支持很多灵活的策略,同时还具有一些防火墙等安全功能。
常见的硬件有F5、A10。
优点:直接连接交换机,处理网络请求能力强,与系统无关,负载性可以强。可以应用于大量设施、适应大访问量、使用简单。
缺点:成本高,配置冗余.即使网络请求分发到服务器集群,负载均衡设施却是单点配置;无法有效掌握服务器及应使用状态.
5.3 软负载均衡
软件负载均衡是指使用软件的方式来分发和均衡流量。软件负载均衡,分为7层协议和 4层协议。网络协议有七层,基于第四层传输层来做流量分发的方案称为4层负载均衡,例如 LVS,而基于第七层应用层来做流量分发的称为7层负载均衡,例如 Nginx。这两种在性能和灵活性上是有些区别的。
基于4层的负载均衡性能要高一些,一般能达到几十万/秒的处理量,而基于7层的负载均衡处理量一般只在几万/秒。基于软件的负载均衡的特点也很明显,便宜。在正常的服务器上部署即可,无需额外采购,就是投入一点技术去优化优化即可,因此这种方式是互联网公司中用得最多的一种方式。
软件负载均衡是最常见的,大小公司都需要用到它。
软件负载均衡是通过负载均衡功能的软件来实现负载均衡,常见的软件有LVS、Openresty、Nginx、HAProxy、Apache、Tengine、SLB/ELB/CLB。
软件负载均衡又分四层和七层负载均衡,四层负载均衡就是在网络层利用IP地址端口进行请求的转发,基本上就是起个转发分配作用。而七层负载均衡就是可以根据访问用户的HTTP请求头、URL信息将请求转发到特定的主机。
负载均衡分类 |
常见软件 |
四层负载 |
LVS,F5,Openresty、Nginx、HAProxy、Apache、Tengine、SLB |
七层负载 |
Openresty、Nginx、HAProxy、Apache、Tengine、SLB/ELB/CLB、MySQL Proxy |
6 四层和七层负载均衡
6.1 什么是四层/七层负载均衡
负载均衡又分为四层负载均衡和七层负载均衡。
四层负载均衡工作在OSI模型的传输层,主要工作是转发,它在接收到客户端的流量以后通过修改数据包的地址信息将流量转发到应用服务器。
七层负载均衡工作在OSI模型的应用层,因为它需要解析应用层流量,所以七层负载均衡在接到客户端的流量以后,还需要一个完整的TCP/IP协议栈。七层负载均衡会与客户端建立一条完整的连接并将应用层的请求流量解析出来,再按照调度算法选择一个应用服务器,并与应用服务器建立另外一条连接将请求发送过去,因此七层负载均衡的主要工作就是代理。
6.2 技术原理上的区别
所谓四层负载均衡,也就是主要通过报文中的目标地址和端口,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。
以常见的TCP为例,负载均衡设备在接收到第一个来自客户端的SYN 请求时,即通过上述方式选择一个最佳的服务器,并对报文中目标IP地址进行修改(改为后端服务器IP),直接转发给该服务器。TCP的连接建立,即三次握手是客户端和服务器直接建立的,负载均衡设备只是起到一个类似路由器的转发动作。在某些部署情况下,为保证服务器回包可以正确返回给负载均衡设备,在转发报文的同时可能还会对报文原来的源地址进行修改。
所谓七层负载均衡,也称为“内容交换”,也就是主要通过报文中的真正有意义的应用层内容,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。
以常见的TCP为例,负载均衡设备如果要根据真正的应用层内容再选择服务器,只能先代理最终的服务器和客户端建立连接(三次握手)后,才可能接受到客户端发送的真正应用层内容的报文,然后再根据该报文中的特定字段,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。
负载均衡设备在这种情况下,更类似于一个代理服务器。负载均衡和前端的客户端以及后端的服务器会分别建立TCP连接。所以从这个技术原理上来看,七层负载均衡明显的对负载均衡设备的要求更高,处理七层的能力也必然会低于四层模式的部署方式。那么,为什么还需要七层负载均衡呢?
7 负载均衡使用场景
7.1 场景一:应用于高访问量的业务
如果您的应用访问量很高,您可以通过配置监听规则将流量分发到不同的服务器上。
7.2 场景二:横向扩张系统
您可以根据业务发展的需要,通过随时添加和移除服务器,来扩展应用系统的服务能力,适用于各种Web服务器和App服务器。
7.3 场景三:消除单点故障
当其中一部分服务器发生故障后,负载均衡会自动屏蔽故障的服务器,将请求分发给正常运行的服务器,保证应用系统仍能正常工作。
7.4 场景四:同城容灾(多可用区容灾)
为了提供更加稳定可靠的负载均衡服务,当主可用区出现机房故障或不可用时,负载均衡仍然有能力在非常短的时间内切换到另外一个备可用区恢复服务能力;当主可用区恢复时,负载均衡同样会自动切换到主可用区提供服务,保证服务依然正常运行。
8 负载均衡的实现原理
8.1 DNS域名解析负载均衡(GSLB)
利用DNS处理域名解析请求的同时进行负载均衡是另一种常用的方案。在DNS服务器中配置多个A记录,如:www.mysite.com IN A 114.100.80.1、www.mysite.com IN A 114.100.80.2、www.mysite.com IN A 114.100.80.3.
每次域名解析请求都会根据负载均衡算法计算一个不同的IP地址返回,这样A记录中配置的多个服务器就构成一个集群,并可以实现负载均衡。
DNS域名解析负载均衡的优点是将负载均衡工作交给DNS,省略掉了网络管理的麻烦,缺点就是DNS可能缓存A记录,不受网站控制。事实上,大型网站总是部分使用DNS域名解析,作为第一级负载均衡手段,然后再在内部做第二级负载均衡。
优点:
1) 将负载均衡的工作丢给了DNS服务器去做,省去了网站管理人员的维护工作
2) 对于真实地址的服务器,不需要做任何的配置
3) 简单易用,成本低,而且方便灵活
4) 服务器可以放在任何的地方
5) DNS服务还可以做基于地理位置的解析,可以让一个距离最近的服务器的IP地址放回,提高性能
缺点:
1) DNS服务是有多级的(之后有时间写一个详细的DNS服务介绍)
大致上来说,首先是在浏览器中有一个DNS缓存,如果找不到就在本机地址的hosts文件中查找,再找不到就去路由器缓存中查找。然后是本地DNS服务器,如果没有,就是根服务器,顶级服务器,权限域名服务器等等;总之,在每一级都有可能缓存这DNS的对应关系,所以有可能当某一台真实服务器下线之后,修改了DNS服务器的记录,但在生效之前还有一段时间,在这段期间,其IP地址已经不可用了,通过域名进行访问时还是会访问到这个IP地址。会访问失败
2) DNS服务器和真实服务器是完全分开的,所以DNS的负载均衡不能监测到真是服务器当前的运行状态,其负载均衡的效果不是很好
3) 可能会造成额外的网络问题。为了使本DNS服务器和其他DNS服务器及时交互,保证DNS数据及时更新,使地址能随机分配,一般都要将DNS的刷新时间设置的较小,但太小将会使DNS流量大增造成额外的网络问题。事实上,大型网站都将DNS负载均衡作为第一级的负载均衡手段,在服务器内部再进行第二级的负载均衡,也就是说,我们通过DNS得到的IP地址并不是真实服务器的IP地址,而是内部负载均衡服务器的IP地址。
8.2 数据链路层负载均衡(LVS)
数据链路层负载均衡是指在通信协议的数据链路层修改mac地址进行负载均衡。
这种数据传输方式又称作三角传输模式,负载均衡数据分发过程中不修改IP地址,只修改目的的mac地址,通过配置真实物理服务器集群所有机器虚拟IP和负载均衡服务器IP地址一样,从而达到负载均衡,这种负载均衡方式又称为直接路由方式(DR).
在上图中,用户请求到达负载均衡服务器后,负载均衡服务器将请求数据的目的mac地址修改为真是WEB服务器的mac地址,并不修改数据包目标IP地址,因此数据可以正常到达目标WEB服务器,该服务器在处理完数据后可以经过网管服务器而不是负载均衡服务器直接到达用户浏览器。
使用三角传输模式的链路层负载均衡是目前大型网站所使用的最广的一种负载均衡手段。在linux平台上最好的链路层负载均衡开源产品是LVS(linux virtual server)。
8.3 IP负载均衡(SNAT)
IP负载均衡:即在网络层通过修改请求目标地址进行负载均衡。
用户请求数据包到达负载均衡服务器后,负载均衡服务器在操作系统内核进行获取网络数据包,根据负载均衡算法计算得到一台真实的WEB服务器地址,然后将数据包的IP地址修改为真实的WEB服务器地址,不需要通过用户进程处理。真实的WEB服务器处理完毕后,相应数据包回到负载均衡服务器,负载均衡服务器再将数据包源地址修改为自身的IP地址发送给用户浏览器。
这里的关键在于真实WEB服务器相应数据包如何返回给负载均衡服务器,一种是负载均衡服务器在修改目的IP地址的同时修改源地址,将数据包源地址改为自身的IP,即源地址转换(SNAT),另一种方案是将负载均衡服务器同时作为真实物理服务器的网关服务器,这样所有的数据都会到达负载均衡服务器。
IP负载均衡在内核进程完成数据分发,较反向代理均衡有更好的处理性能。但由于所有请求响应的数据包都需要经过负载均衡服务器,因此负载均衡的网卡带宽成为系统的瓶颈。
优点:IP负载均衡在内核进程完成数据分发,处理性能得到了很好的提高。
缺点:由于所有请求和响应都要经过负载均衡服务器,集群的最大响应数据吞吐量将受到负载均衡服务器网卡带宽的限制,对于提供下载服务或者视频服务等需要大量传输数据的站点而言,这是难以满足需求的
8.4 HTTP重定向负载均衡(少见)
HTTP重定向服务器是一台普通的应用服务器,其唯一的功能就是根据用户的HTTP请求计算一台真实的服务器地址,并将真实的服务器地址写入HTTP重定向响应中(响应状态吗302)返回给浏览器,然后浏览器再自动请求真实的服务器。
这种负载均衡方案的优点是比较简单,缺点是浏览器需要每次请求两次服务器才能拿完成一次访问,性能较差;使用HTTP302响应码重定向,可能是搜索引擎判断为SEO作弊,降低搜索排名。重定向服务器自身的处理能力有可能成为瓶颈。因此这种方案在实际使用中并不见多。
8.5 反向代理负载均衡(nginx)
传统代理服务器位于浏览器一端,代理浏览器将HTTP请求发送到互联网上。而反向代理服务器则位于网站机房一侧,代理网站web服务器接收http请求。
反向代理的作用是保护网站安全,所有互联网的请求都必须经过代理服务器,相当于在web服务器和可能的网络攻击之间建立了一个屏障。
除此之外,代理服务器也可以配置缓存加速web请求。当用户第一次访问静态内容的时候,静态内存就被缓存在反向代理服务器上,这样当其他用户访问该静态内容时,就可以直接从反向代理服务器返回,加速web请求响应速度,减轻web服务器负载压力。
另外,反向代理服务器也可以实现负载均衡的功能。
由于反向代理服务器转发请求在HTTP协议层面,因此也叫应用层负载均衡。优点是部署简单,缺点是可能成为系统的瓶颈。
9 负载均衡的算法
9.1 随机算法
Random随机,按权重设置随机概率。在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。
9.2 轮询
轮询算法把每个请求轮流发送到每个服务器上。
下图中,一共有 6 个客户端产生了 6 个请求,这 6 个请求按 (1, 2, 3, 4, 5, 6) 的顺序发送。(1, 3, 5) 的请求会被发送到服务器 1,(2, 4, 6) 的请求会被发送到服务器 2。
该算法比较适合每个服务器的性能差不多的场景,如果有性能存在差异的情况下,那么性能较差的服务器可能无法承担过大的负载。
轮询(Round Robbin)当服务器群中各服务器的处理能力相同时,且每笔业务处理量差异不大时,最适合使用这种算法。轮循,按公约后的权重设置轮循比率。存在慢的提供者累积请求问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。
9.3 加权轮询
加权轮询是在轮询的基础上,根据服务器的性能差异,为服务器赋予一定的权值,性能高的服务器分配更高的权值。
例如下图中,服务器 1 被赋予的权值为 5,服务器 2 被赋予的权值为 1,那么 (1, 2, 3, 4, 5) 请求会被发送到服务器 1,(6) 请求会被发送到服务器 2。
加权轮询(Weighted Round Robbin)为轮询中的每台服务器附加一定权重的算法。
9.4 最小连接
由于每个请求的连接时间不一样,使用轮询或者加权轮询算法的话,可能会让一台服务器当前连接数过大,而另一台服务器的连接过小,造成负载不均衡。
例如下图中,(1, 3, 5) 请求会被发送到服务器 1,但是 (1, 3) 很快就断开连接,此时只有 (5) 请求连接服务器 1;(2, 4, 6) 请求被发送到服务器 2,只有 (2) 的连接断开,此时 (6, 4) 请求连接服务器 2。该系统继续运行时,服务器 2 会承担过大的负载。
最少连接算法就是将请求发送给当前最少连接数的服务器上。
例如下图中,服务器 1 当前连接数最小,那么新到来的请求 6 就会被发送到服务器 1 上。
最少连接(Least Connections)在多个服务器中,与处理连接数(会话数)最少的服务器进行通信的算法。即使在每台服务器处理能力各不相同,每笔业务处理量也不相同的情况下,也能够在一定程度上降低服务器的负载。
9.5 加权最小连接
在最少连接的基础上,根据服务器的性能为每台服务器分配权重,再根据权重计算出每台服务器能处理的连接数。
加权最少连接(Weighted Least Connection)为最少连接算法中的每台服务器附加权重的算法,该算法事先为每台服务器分配处理连接的数量,并将客户端请求转至连接数最少的服务器上。
9.6 源地址哈希法 (IP Hash)
源地址哈希通过对客户端 IP 计算哈希值之后,再对服务器数量取模得到目标服务器的序号。
可以保证同一 IP 的客户端的请求会转发到同一台服务器上,用来实现会话粘滞(Sticky Session)
通过管理发送方IP和目的地IP地址的散列,将来自同一发送方的分组(或发送至同一目的地的分组)统一转发到相同服务器的算法。当客户端有一系列业务需要处理而必须和一个服务器反复通信时,该算法能够以流(会话)为单位,保证来自相同客户端的通信能够一直在同一服务器中进行处理。
9.7 哈希算法
普通哈希
一致性哈希一致性Hash,相同参数的请求总是发到同一提供者。当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。
9.8 URL散列
通过管理客户端请求URL信息的散列,将发送至相同URL的请求转发至同一服务器的算法。
THE END
声明:在文档编制和内容整理过程中,参考了网络上公开发表的部分内容,如有引述已在图片中保留水印。