想一个问题:假设你有10台服务器对外提供相同的服务
,你如何保证这10台服务器能稳定处理外部请求?负载 这里可能有很多种解决方案 ,但本质上都是循序处理下述两个问题 : ① 客户端的请求应该分配去哪一台服务器比较好? ② 万一其中某些服务器故障了,如何隔离掉故障服务器?渐进讲解均衡 问题① 处理不好,可能会导致10台服务器中的负载一部分服务器处于饥饿状态,没有被分配客户端请求或者是循序分配得很少;而另一部分则一直在处理大量的请求,导致不堪负重 。渐进讲解均衡 问题② 处理不好
,负载则CAP原则中的亿华云循序可用性(A)可能就没法保证,除非系统不需要A
。渐进讲解均衡 要解决上述问题,负载你必须实现一套控制器 ,循序能调度业务请求和管理业务服务器。渐进讲解均衡很不幸的负载是
,大多数情况下这个控制器往往就是整个系统的瓶颈 。因为控制系统如果不深入到客户端上,就必须依赖一个集中式的决策机构 ,这个机构必然要承载所有客户端的请求
。源码库这时候你又得去考虑这个控制器的冗余和故障隔离的问题,这就变得无休无止。 那么,如何解决上述问题? 那就是专业的事情交给专业平台去做
,即,我们需要独立的负载均衡提供上述2点的解决方案
。 对于客户端来说,每次请求一个站点,最终都会转变成对某个IP发起请求。高防服务器所以只要能控制客户端访问的IP地址
,我们就能控制请求应该落到哪个后端服务器上 ,从而达到调度效果 ,这是DNS在做的事情。或者,劫持客户端所有请求流量
,对流量重新分配请求到后端服务器上。这个是Nginx、LVS等的处理方式。 图1、通过DNS实现负载均衡的服务器租用效果示意图 图2、通过LVS/Nginx实现负载均衡的效果示意图 这两个方式都能达到负载均衡的效果。但这里面有个严重的问题 ,DNS、Nginx、LVS等服务在互联网时代不可能单机就能提供业务 ,都是集群式(也就是有N台服务器组成)
,那这些集群的可靠性和稳定性又该如何保证呢
? DNS主要负责域名解析,有一定的负载均衡效果,云计算但往往负载效果很差
,不作为主要考虑手段。Nginx提供7层负载均衡,主要靠域名来做业务区分和负载。LVS是4层负载均衡,主要靠TCP/UDP协议
、IP地址 、TCP/UDP端口来区分服务和负载。 为了解决Nginx、LVS这些负载均衡器集群的负载均衡及可靠性 ,我们可以做下述简单的方案
: 上述方案是遵循了业务 <-- 7层负载 <-- 4层负载的逻辑,实际上是在网络分层模型中的应用层 <-- 传输层的做两级负载
。可以看出 ,其实这个方案是用另一层负载均衡来解决当前层级的负载和可靠性的问题
。但这个方案还是有问题,业务和Nginx集群这两层的负载和可靠性是有保障了,但LVS集群这一层的可靠性怎么办? 既然我们在网络分层模型中应用层 <-- 传输层做了两级负载,那有没有可能做到应用层 <-- 传输层 <-- 网络层的三级负载?很幸运的是,基于IP路由的方式 ,网络设备(交换机、路由器)天然具备了网络层负载均衡功能。 到此
,我们可以实现整个负载均衡链条
:业务 <-- 7层负载(Nginx) <-- 4层负载(LVS) <-- 3层负载(NetworkDevices); 从这里可以看出,要确保整个负载均衡体系是有效可靠的
,必须从网络层开始构筑
。处于高层级的业务
,可以为低层级的业务提供负载。相对于低层级,高层级的业务都可以认为是低层级业务的控制面 ,可以交给专业团队去实现和管理 ,低层级业务侧只需要关注业务本身实现即可。 图3、网络7层模型和LVS
、Nginx之间的对应关系 网络7层分层模型说明
: 7、应用层: 支持网络应用 ,应用协议仅仅是网络应用的一个组成部分
,运行在不同主机上的进程则使用应用层协议进行通信。主要的协议有:HTTP
、FTP
、Telnet、SMTP 、POP3等
。 数据的表示 、安全、压缩。(实际运用中该层已经合并到了应用层) 建立、管理、终止会话。(实际运用中该层已经合并到了应用层) 负责为信源和信宿提供应用程序进程间的数据传输服务
,这一层上主要定义了两个传输协议
,传输控制协议即TCP和用户数据报协议UDP。 负责将数据报独立地从信源发送到信宿,主要解决路由选择
、拥塞控制和网络互联等问题。 负责将IP数据报封装成合适在物理网络上传输的帧格式并传输
,或将从物理网络接收到的帧解封,取出IP数据报交给网络层。 上面说过 ,3层负载由网络设备天然提供
,但实际使用中是和4层负载紧耦合的,一般不独立提供服务 。4层负载可以直接为业务层提供服务,而不依赖7层负载(7层负载主要面向HTTP/HTTPS等业务) ,所以我们这里主要针对4层负载来讲
。 实现负载均衡,言外之意就是实现流量重定向 ,那么 ,首要解决的问题是如何转发流量
。 4个问题要解决: ① 如何把客户端的流量吸引到负载均衡器上
? ② 负载均衡器如何选择合适的后端服务器? ③ 负载均衡器如何将请求数据发送到后端服务器上
? ④ 后端服务器如何响应请求数据? 对于①
, 解决方案很简单,给一批后端服务器提供一个独立的IP地址,我们称之为Virtual IP(也即VIP)
。所有客户端不用直接访问后端IP地址,转而访问VIP 。对于客户端来说
,相当于屏蔽了后端的情况 。 对于②, 考虑到处于低层级的负载均衡通用性,一般不做复杂的负载策略
,类似RR(轮询)、WRR(带权重轮询)的方案更合适,可以满足绝大多数场景要求。 对于③
, 这里的选择会往往会影响这④的选择
。理想情况下,我们期望是客户端的请求数据应该原封不动的发送到后端,这样能避免数据包被修改。前面提到的网络七层分层模型中,数据链路层的转发可以做到不影响更上层的数据包内容,所以可以满足不修改客户端请求数据的情况下转发。这就是网络常说的二层转发(数据链路层,处在七层网络模型中的第二层),依靠的是网卡的MAC地址寻址来转发数据。 那么
,假设把客户端的请求数据包当成一份应用数据打包送到后端服务器是不是可行?该方式相当于负载均衡器和后端建立了一个隧道 ,在隧道中间传输客户端的请求数据
,所以也可以满足需求。 上述两种解决方案中 ,依赖数据链路层转发的方案称之为直接路由方式(Direct Route),即DR模式;另一种需要隧道的方案称之为隧道(Tunnel)模式。DR模式有一个缺点,因为依赖MAC地址转发,后端服务器和负载均衡器必须在同一个子网中(可以不严谨认为是同一个网段内),这就导致了只有和负载均衡服务器在同子网的服务器能接入
,不在同一个子网的这部分就没有使用负载均衡的机会了,这显然不可能满足当前大规模的业务。Tunnel模式也有缺点
:既然数据转发依赖隧道
,那就必须在后端服务器和负载均衡器之间建立隧道。如何确保不同业务人员能正确在服务器上配置隧道,并且能监控隧道正常运行
,难度都很大 ,需要一套完成的管理平台 ,言外之意即管理成本过高
。 图4 、DR模式的转发示意图
,响应流量不会经过负载均衡器 图5、Tunnel模式转发示意图,和DR一样
,响应流量不会经过负载均衡器 既然都不是很理想
,那还有没有其他方案? 我们期望的是后端服务器不感知前端有负载均衡存在,服务可以放在任何地方,且不做任何过多配置 。既然做不到原封不动传送客户端的数据包 ,那就代理客户端的请求
。也就是对客户端发出来的数据包的源IP和目的IP分别做一次IP地址转换 。 详细来说 ,负载均衡器收到客户端A的请求后
,自己以客户端的角色向后端服务器发起相同的请求
,请求所带的payload来自于客户端A的请求payload
,这样保证了请求数据一致。 此时
,负载均衡器相当于发起了一个新连接(不同于客户端A发起的连接),新建的连接将会使用负载均衡器的IP地址(称之为LocalIP)作为源地址直接和后端服务器IP通信 。 当后端返回数据给负载均衡器时,再用客户端A的连接将数据返回给客户端A。整个过程涉及了两个连接,对应两次IP地址转换 , 客户端该过程完全基于IP地址转发数据 ,而不是MAC地址
,只要网络可达
,数据就可以顺畅在客户端和后端之间传输。 图6、FULLNAT转发模式 上述方案称之为FULLNAT转发模式
一
、循序怎么保证你的渐进讲解均衡业务可靠
二 、业务和控制隔离



三、如何实现4层负载均衡


