负载均衡整理

负载均衡是高可用网络基础架构的关键组件,通常用于将工作负载分布到多个服务器来提高网站、应用、数据库或其他服务的性能和可靠性。

实现负载均衡主要有两个目的。第一个目的是将任务的处理负载均摊到不同的进程,以减少单一进程的负载,以达到处理能力水平扩容的目的。第二个目的则是提高容错能力。我们知道,在线上正式环境中,机器宕机或者进程异常导致服务不可用是常有的现象。在实现负载均衡的系统中,多个服务器进程提供同样的服务,一个进程不可用的情况下,任务会被负载均衡器派发到其他可用的进程,以达到高可用的目的。在多台不同的服务器中部署相同的服务进程,通过负载均衡对外提供服务,这组进程也称为“集群”(cluster)

OSI 模型在其第 二 、第三 、第四和第七层均具有相应的负载均衡策略,具体如下 。

基于数据链路层(二层〉的负载均衡

数据链路层位于

OSI 模型的第二层,二层负载均衡通常使用基于 MAC 地址的虚拟 MAC

地址模式来分摊负载。用户对外部虚拟 MAC 地址发起请求,负载均衡设备接收后,为后端分配实际的MAC地址响应。 二层负载均衡技术会提供一个外部VIP (虚拟IP)地址,并且,后台服务器的实际 IP 地址是相同的,实际内部 MAC 地址各不相同 。 那么,服务器 IP 地址相同会产生 E 地址冲突吗?答案是否定的。因为这些服务器都比较特殊,不发送 ARP 报文,并且要求负载均衡设备连接交换机的端口 也不发送 ARP 报文。只要负载均衡设备发出报文,

交换机根据 MAC 地址表项转发即可 。

· 基于网络层 (三层〉的负载均衡

网络层处在 OSI 模型的第三层中。 一般地, 三层负载均衡采用虚拟 IP 地址,是基于 IP地址来实现分摊流量的 。 负载平衡设备提供了 一个外部 VIP (虚拟 IP)地址, 但后台服务器

之间的实际 E 地址是各不相同的 。 客户端请求虚拟 E 地址,负载平衡设备接收后,分配实际 E 地址响应(每个服务器对应不同的实际 E 地址) 。

基于传输层(四层)的负载均衡

传输层位于 OSI模型的第四层,也称为四层负载均衡技术。 四层负载均衡是以三层负载均衡为基础的,通过三层的虚拟IP (VIP)地址, 再添加四层的端口号来实现的,自|]用IP地址+端口接收请求,再转发到对应的服务器。在三层负载均衡的基础上加上端口号的目的地址,用来决定哪些流量需要进行负载均衡处理。处理这些流量并转发到后端服务器,然后记录 TCP 或 UDP 流量是由哪个服务器处理的,后续将这个连接的所有的流量也转发到同 一服务器进行处理。 LVS 就是一个常见的传输层开源负载均衡工具。

基于应用层(第七层〉的负载均衡

应用层在OSI 模型的第七层,也称第七层负载均衡,就是基于虚拟 URL 等应用层信息,的负载均衡,例如,客户端通过请求虚拟 URL,分配给用户真正提供服务的服务器。七层负载均衡的优点是使整个网络变得更加智能 。 例如, 当通过七级负载均衡方式访问网站时,对于图片类请求能够被转发到特定缓存服务器,并可用缓存技术实现负载均衡;对于文本类请求可通过特定的文本压缩技术,减轻负载 。 当然,这只是七层负载均衡应用的两个小例子,从技术原理上讲,七层负载均衡能够极大地提高网络层应用系统的灵活性 。 常见的应用层开源负载均衡工具有 Nginx 和 Apache。

负载均衡器可以处理什么样的请求?

负载均衡器的管理员能主要为下面四种主要类型的请求设置转发规则:

HTTP,HTTPS,TCP,UDP

技术原理上的区别。

所谓四层负载均衡,也就是主要通过报文中的目标地址和端口,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。

以常见的TCP为例,负载均衡设备在接收到第一个来自客户端的SYN 请求时,即通过上述方式选择一个最佳的服务器,并对报文中目标IP地址进行修改(改为后端服务器IP),直接转发给该服务器。TCP的连接建立,即三次握手是客户端和服务器直接建立的,负载均衡设备只是起到一个类似路由器的转发动作。在某些部署情况下,为保证服务器回包可以正确返回给负载均衡设备,在转发报文的同时可能还会对报文原来的源地址进行修改。

所谓七层负载均衡,也称为“内容交换”,也就是主要通过报文中的真正有意义的应用层内容,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。

以常见的TCP为例,负载均衡设备如果要根据真正的应用层内容再选择服务器,只能先代理最终的服务器和客户端建立连接(三次握手)后,才可能接受到客户端发送的真正应用层内容的报文,然后再根据该报文中的特定字段,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。



负载均衡整理_第1张图片

当然这只是七层应用的一个小案例,从技术原理上,这种方式可以对客户端的请求和服务器的响应进行任意意义上的修改,极大的提升了应用系统在网络层的灵活性。很多在后台,(例如Nginx或者Apache)上部署的功能可以前移到负载均衡设备上,例如客户请求中的Header重写,服务器响应中的关键字过滤或者内容插入等功能。

另外一个常常被提到功能就是安全性。网络中最常见的SYN Flood攻击,即黑客控制众多源客户端,使用虚假IP地址对同一目标发送SYN攻击,通常这种攻击会大量发送SYN报文,耗尽服务器上的相关资源,以达到Denial of Service(DoS)的目的。

从技术原理上也可以看出,四层模式下这些SYN攻击都会被转发到后端的服务器上;而七层模式下这些SYN攻击自然在负载均衡设备上就截止,不会影响后台服务器的正常运营。另外负载均衡设备可以在七层层面设定多种策略,过滤特定报文,例如SQL Injection等应用层面的特定攻击手段,从应用层面进一步提高系统整体安全。

现在的7层负载均衡,主要还是着重于应用广泛的HTTP协议,所以其应用范围主要是众多的网站或者内部信息平台等基于B/S开发的系统。 4层负载均衡则对应其他TCP应用,例如基于C/S开发的ERP等系统。

负载均衡器如何选择要转发的后端服务器?

负载均衡器一般根据两个因素来决定要将请求转发到哪个服务器。首先,确保所选择的服务器能够对请求做出响应,然后根据预先配置的规则从健康服务器池(healthy pool)中进行选择。

因为,负载均衡器应当只选择能正常做出响应的后端服务器,因此就需要有一种判断后端服务器是否「健康」的方法。为了监视后台服务器的运行状况,运行状态检查服务会定期尝试使用转发规则定义的协议和端口去连接后端服务器。如果,服务器无法通过健康检查,就会从池中剔除,保证流量不会被转发到该服务器,直到其再次通过健康检查为止。

负载均衡流量从进出来分,可以分为出SLB,即为服务器提供负载均衡,一台负载均衡身后有多台服务器,用户访问SLB,由SLB对流量进行调度,分发至不同的服务器,这种可以理解为inbound流量,也就是常说的负载均衡。第二种是针对由内到网的负载,LLB也就是链路负载,办公网的流量访问互联网,分别走联通还是电信,或者基于源IP的负载均衡,说明SLB即针对服务器的流量或服务调度。

SLB的主要功能分为两个作用,第一个是调度流量,通过一种或多种算法,将用户的请求调度到身后不同的服务器上,例如最简单的轮询算法,即平均分配。第二个作用是健康检查,即对SLB身后的服务器或服务进行检查,例如哪一台服务器故障了,或者服务不能正常工作了,就将这台服务器移除,不再请求转发到服务器上,始终提供良好的服务,SLB还可以隐藏服务器的真实IP,使得服务器不暴露在公网,降低发现和攻击的风险,七层负载均衡还可以做SSL证书的加载,减轻后端web服务端的压力和操作。

从节点构成的角度来说,无论是 CDN 区域层节点还是 CDN 边缘层节点,都是由缓存设备和本地负载均衡设备( SLB)构成的。在一个 CDN 节点中,缓存设备和本地负载均衡设备的连接方式有两种: 一种是旁路方式,另一种是穿越方式,在穿越方式下, SLB 一般由四七层交换机实现, SLB 向外提供可访问(公网〉的虚拟 E(VIP)地址,每台缓存设备分配不同的私网 E 地址,该 SLB 连接下挂的所有缓存设备构成一个服务单元 。所有用户请求经由该 SLB 设备,再由 该 SLB 向上向下进行转发 。 SLB 实际上承担了网络地址转换( Network Address Translation, NAT)功能,向用户隐藏了各台 缓存设备设备的 E 地址。这种方式是 CDN 系统中应用较多的方式,优点是具有较高的安全性和可靠性,但是,当节点容量大时-,四七层交换机容易形成性能瓶颈。


负载均衡整理_第2张图片

负载均衡按照OSI模型可以分为四层和七层负载均衡,四层负载均衡是指对IP地址或端口进行负载,例如可以调度http流量,dns流量和数据库流量,只要是基于TCP或者UDP都可以调度,基于IP或者端口来实现,常见的有软件LVS.七层负载均衡主要针对web应用,对应用层内容进行调度,例如基于某个URL进行调度,七层负载均衡也叫做反向代理,常见的软件有Haproxy和Nginx.

总之, 二层负载均衡为 : 收到一个对虚拟 MAC 地址的请求,然后分配给用户实际 MAC地址的服务器以提供服务: 三层负载均衡为 :收到一个对虚拟 IP地址的请求,然后分配给用户实际 IP 地址的服务器以提供服务;四层负载均衡为 : 一个虚拟 E 地址+端口的方式,确定什么样的流量需要进行负载均衡,并为用户分配实际的服务器以提供服务:七层负载均衡为:

接收对虚拟 URL 的请求,然后分配给用户实际提供服务的设备以提供服务。所谓 4~7 层负载均衡,就是在需要对后台服务器进行负载均衡的背景下,根据四层信息或七层信息来确定转发流量的策略。

为什么需要DNS进行负载

当业务量增加以后,一台负载均衡器和20台服务器,如果需要增加一台新的负载均衡器和20台服务器,两台负载均衡器对应两个公网IP地址,即一个域名可以对应多个IP地址记录,使用轮询机制进行调度,即用户A查询域名www.abc.com返回的是119.1.1.1,而用户B查询域名返回的是119.1.1.2.这时候两个用户的公网IP是不同的,最顶端调度实现了,再通过四层负载均衡,七层负载均衡进行流量调度,

应用程序负载均衡器

在应用程序层 (HTTP/HTTPS) 作出路由决策,支持基于路径的路由,并且可以将请求路由到集群中每个容器实例上的一个或多个端口。应用程序负载均衡器支持动态主机端口映射。例如,如果任务的容器定义指定端口 80 为 NGINX 容器端口,并指定端口 0为主机端口,则从容器实例的临时端口范围(例如,在最新的Amazon ECS-optimized AMI 上,为 32768 到61000)中动态选择主机端口。在启动任务时,NGINX 容器将作为实例 ID 和端口组合注册到 应用程序负载均衡器,并且流量将分配到与该容器对应的实例 ID和端口。此动态映射可让您在同一容器实例上拥有来自单个服务的多个任务。有关更多信息,这是一个七层负载均衡产品,主要对http和https内容进行负载。 

网络负载均衡器,可以对端口进行三四层转发

在传输层 (TCP/SSL)制定路由决策。它每秒可以处理数百万个请求。在负载均衡器收到连接后,它会使用流式哈希路由算法从目标组中选择一个目标作为默认规则。它尝试在侦听器配置中指定的端口上打开一个到该选定目标的TCP 连接。它转发请求,而不修改标头。网络负载均衡器 支持动态主机端口映射。例如,如果任务的容器定义指定端口 80 为 NGINX 容器端口,并指定端口 0为主机端口,则从容器实例的临时端口范围(例如,在最新的Amazon ECS-optimized AMI 上,为 32768 到61000)中动态选择主机端口。在启动任务时,NGINX 容器将作为实例 ID 和端口组合注册到 网络负载均衡器,并且流量将分配到与该容器对应的实例 ID和端口。此动态映射可让您在同一容器实例上拥有来自单个服务的多个任务

实例:

1.创建EC2实例,一台在可用区A,另一台在可用区B,两个实例应用SG-WEB这个安全组,出站和入站规则全部放行80和22端口,同时安装httpd服务

2.在两台服务器上创建index.html,模拟web服务器,主要是为了测试负载均衡器。

3.创建目标组,主要是为了负载均衡用于把哪一类流量调度到哪一个组,业务应该是完全相同的。将两台服务器进行注册


负载均衡整理_第3张图片

4.此时发现还是unused,还没有被负载均衡所使用,接着在EC大选项中,选择负载均衡器,创建负载均衡器


负载均衡整理_第4张图片

5.模式选择面对internet,向互联网提供服务的,IP选择IPV4,添加HTTP和80端口


负载均衡整理_第5张图片

配置安全组以及目标应用过来,点击应用即可用


负载均衡整理_第6张图片
负载均衡整理_第7张图片

问题剖析

1. Nginx负载均衡的算法怎么实现的?策略有哪些?

负载均衡是 Nginx常用的一个功能,当一台服务器在单位时间内的访问量越大时,服务器压力就越大,大到超过自身承受能力时,服务器就会崩溃。

为了避免服务器崩溃,大家会通过负载均衡的方式来分担服务器压力。将对台服务器组成一个集群,当用户访问时,先访问到一个转发服务器,再由转发服务器将访问分发到压力更小的服务器。

负载均衡整理_第8张图片

(1) 轮询(默认)

每个请求按时间顺序逐一分配到不同的后端服务器,如果后端某个服务器宕机,能自动剔除故障系统。

新的连接被依次轮询分发到各个实服务上,比如第一个连接分发到第一台服务器,第二个连接分发到第二台服务器上;轮询算法适用于服务器集群中所有服务器都有相同的软硬件配置,并且平均服务器请求相对均衡的情况

upstream backserver { 

 server 192.168.0.12;  server 192.168.0.13; 

(2) 权重 weight

weight的值越大分配到的访问概率越高,主要用于后端每台服务器性能不均衡的情况下。其次是为在主从的情况下设置不同的权值,达到合理有效的地利用主机资源。

根据服务器不同的处理能力,给服务器分配不同的权值,使其能接受相应权值的服务器请求;加权轮询算法能确保高性能的服务器能得到更多的使用率,避免低性能的服务器过载过重;

upstream backserver { 

server 192.168.0.12weight=2; server 192.168.0.13weight=8; 

权重越高,在被访问的概率越大,如上例,分别是20%,80%。

(3) ip_hash( IP绑定)

每个请求按访问IP的哈希结果分配,使来自同一个IP的访客固定访问一台后端服务器,并且可以有效解决动态网页存在的session共享问题

upstream backserver { 

 ip_hash; 

 server 192.168.0.12:88; server 192.168.0.13:80; 

常见的负载均衡实现策略有以下几种:

- 均匀派发(Even Task Distribution Scheme)- 加权派发(Weighted Task Distribution Scheme)

- 粘滞会话(Sticky Session Scheme)- 均匀任务队列派发(Even Size Task Queue Distribution Scheme)

- 单一队列(Autonomous Queue Scheme)

1.均匀派发是实现负载均衡最简单的策略,均衡派发的意思是指任务将均匀地派发到所有的服务器进程。在实现时,可以使用随机派发或者轮流派发(Round Robin)

2.加权派发策略在派发任务时,会赋予服务器进程一个权值,即不同的进程会接受不同数量的任务,具体数量为权值确定。

3.前面两种负载均衡策略并没有考虑任务之间的依赖关系,在实际中,后面的任务处理常常会依赖于前面的任务。例如,对于同一个登录的用户的请求,用户购买的请求依赖于用户登录的请求,如果用户的登录信息保存在进程1中,那么,如果购买请求被分派到进程2或者进程3,那么购买请求将不能正确处理。这种请求间的依赖关系也称为粘滞会话(Sticky Session),负载均衡策略需要考虑粘滞会话的情况。

4.均匀任务队列派发

均匀任务队列派发策略跟加权派发策略类似,都考虑了进程的处理能力,不过其实现方式不同。在均匀队列派发策略下,负载均衡器为每个进程都创建一个大小相等的任务队列,这些任务队列包含了对应进程需要处理的任务。任务处理快的进程,其队列也会减少得快,这样负载均衡器会派发更多的任务给这个进程;相应地,任务处理慢的进程,其队列也会减少得慢,这样负载均衡器会派发更少的任务给这个进程。

5.单一队列

单一队列策略中,实际上并没有负载均衡器的存在。所有的服务器进程从队列中取出任务执行,如果某个进程出现宕机的情况,那么其他进程仍然可以继续执行任务。这样一来,任务队列并不需要知道服务进程的情况,只需要服务进程知道自己的任务队列,并不断执行任务即可。

硬件负载均衡器三大功能

上面谈到硬件负载均衡器的作用和特点,它具备哪三大功能?实现原理又是怎样的?

①多链路负载均衡

关键业务都需要安排和配置多条 ISP(网络服务供应商)接入链路来保证网络服务的可靠性。

如果某个 ISP 停止服务或者服务异常了,那么可以利用另一个 ISP 替代服务,提高了网络的可用性。

不同的 ISP 有不同自治域,因此需要考虑两种情况:

INBOUND

OUTBOUND

INBOUND,来自网络的请求信息。F5 分别绑定两个 ISP 服务商的公网地址,解析来自两个 ISP 服务商的 DNS 解析请求。

F5 可以根据服务器状况和响应情况对 DNS 进行发送,也可以通过多条链路分别建立 DNS 连接。

OUTBOUND,返回给请求者的应答信息。F5 可以将流量分配到不同的网络接口,并做源地址的 NAT(网络地址转换),即通过 IP 地址转换为源请求地址。

防火墙会对用户会话的双向数据流进行监控,从而确定数据的合法性。如果采取多台防火墙进行负载均衡,有可能会造成同一个用户会话的双向数据在多台防火墙上都进行处理。

而单个防火墙上看不到完成用户会话的信息,就会认为数据非法因此抛弃数据。

所以在每个防火墙的两端要架设四层交换机,可以在作流量分发的同时,维持用户会话的完整性,使同一用户的会话由一个防火墙来处理。而这种场景就需要 F5 负载均衡器协助才能完成转发。


负载均衡整理_第9张图片

1.对于服务器的负载均衡的前提是,服务器都提供同样的服务,也就是同样的业务同时部署在多个服务器上。

2.对于应用服务器可以在 F5 上配置并且实现负载均衡,F5 可以检查服务器的健康状态,如果发现故障,将其从负载均衡组中移除。

3.F5 对于外网而言有一个真实的 IP,对于内网的每个服务器都生成一个虚拟 IP,进行负载均衡和管理工作。因此,它能够为大量的基于 TCP/IP 的网络应用提供服务器负载均衡服务。

4.根据服务类型不同定义不同的服务器群组。

5.根据不同服务端口将流量导向对应的服务器。甚至可以对 VIP 用户的请求进行特殊的处理,把这类请求导入到高性能的服务器使 VIP 客户得到最好的服务响应。

6.根据用户访问内容的不同将流量导向指定服务器。

软件负载均衡

说完硬件负载均衡,再来谈谈软件负载均衡。软件负载均衡是指在一台或多台服务器的操作系统上安装一个或多个软件来实现负载均衡。

功能描述和原理分析

对于程序员来说,接触最多的就是软件负载均衡。不仅要知道如何使用,同时也要了解背后的原理,下面列举了其最常用到的 4 大功能。

①反向代理与负载均衡

第一个功能是反向代理与负载均衡,如下图:


负载均衡整理_第10张图片

客户端是如何把请求发送到应用服务器的

客户端把请求发送到应用服务器有如下几个步骤:

1.客户端请求 URL 给 DNS。

2.DNS 将 URL 转化成对应的 IP。

3.通过 IP 找到服务器。

4.服务器接受到请求的报文,转交给接入层处理,接入层由于采用了硬件负载均衡器,所以能够扛住大数据量。

5.接入层把报文再次转交给代理层(并发 5W),代理层的 Nginx 收到报文再根据反向代理的策略发送给上游服务器(应用服务器)。

②动态负载均衡

微服务首先会注册到“服务注册发现”中心(Consul,Eureka)。注册中心包含微服务的信息,Nginx 会定期从这里拉取服务信息(Lua)。

获取微服务信息以后,Nginx 收到数据报的时候,就可以从注册中心获取的服务地址,把信息传递给服务了。

③限流

限流的工作可以在接入层用硬件负载均衡器来完成,也可以在代理层来完成。

限流实际上就是限制流入请求的数量,其算法不少,有令牌桶算法,漏桶算法,连接数限制等等。这里我们就介绍三个常用的。一般通过 Nignx+Lua 来实现。

连接数限流:通过 ngx_http_limit_conn_module 模块实现。设置最大的连接数以及共享内存的区域大小,请求的时候判断是否超过了最大连接数。

如果超过最大连接数就被限流,否则针对连接数就 +1,请求结束以后会将连接数 -1。

漏桶算法:通过 ngx_http_limit_req_module 模块实现。一个固定容量的桶,数据报按照固定的速度流出。

数据报可以按照任意的速度流入桶中,如果数据报的容量超过了桶的容量,再流入的数据报将会被丢弃。

按照这个规则,需要设置限流的区域以及桶的容量,以及是否延迟。


负载均衡整理_第11张图片

漏桶策略

令牌桶算法,桶的大小是固定的,以固定的速度往桶里丢令牌。桶满了后,后面添加的令牌无法添加。

数据报到来时从桶中取令牌,如果桶中有令牌,凭借令牌处理请求,处理完毕令牌销毁;数据报到来时发现桶中没令牌,该请求将被拒绝。

请求在发往令牌桶之前需要经过过滤/分类器,可以对报文进行分类,例如:某类报文可以直接发往应用服务器,某类报文需要经过令牌桶获取令牌以后才能发。

④缓存

负载均衡整理_第12张图片

Nginx 本地缓存机制

接入层发送请求,如果能够在 Nginx 本地缓存命中,直接返回缓存数据,如果没有命中回源到应用服务器。

缓存更新服务器定时更新 Nginx 本地缓存信息。这些需要考虑数据的一致性,何时更新以及何时失效等情况。

Nginx 缓存可以大大提高请求响应时间,可以把不经常更改的信息,例如:用户信息,提前放入缓存中,每次请求就不用再去请求应用服务器了。一旦用户信息更新,可以按照一定时钟频率写入缓存中。

另外,一般 HTTPHEAD 中都带有一些信息更新的信息。Nginx 也可以通过 expires,etag,if-modified-since 来实现浏览器缓存的控制。

其他的几个功能如下:

客户端超时重试,DNS 超时重试,代理超时重试,失败重试,心跳检测,配置上有服务器。

你可能感兴趣的:(负载均衡整理)