大型web项目构建之负载均衡
日常开发和学习中经常会听到或者会看到“负载均衡”这个词汇,但是对于很多初级每天只面对增删改代码的开发人员来说,这个词汇好像离我们很遥远又很接近,很多人多多少少都有点一知半解
我结合以前在开发中遇到的场景和通过查阅相关资料来简单了解一下词汇之一 ——“负载均衡”
负载均衡的基本理解以及基本概念:
简单理解:如果你是第一次听到这个词,那么你可以这样简单的去理解——负载均衡是什么?答:它是一种的技术,具有很多实现方式,可以从软件(nginx等)或者硬件(负载均衡器)上去实现。负载均衡有啥用?答:主要作用就是用来提升服务器性能,可以处理更多的请求和更大量的数据
基本概念:将负载进行平衡,负载均衡是高可用网络基础架构的的一个关键组成部分,负载均衡(Load Balance)其意思就是将多个相同功能或者相似功能的服务(如web服务,ftp服务,企业关键应用服务等)分摊到多个操作单元上进行执行,共同完成工作任务。
单纯从上面的概念去理解负载均衡肯定会让人有点懵。我们不如先来看一看传统不使用负载均衡的传统服务器架构,然后在对比学习使用了负载均衡各种的架构,这样你可能就会对负载均衡这一概念会有更好的理解。
1 传统服务器简单架构#
1.1 传统服务器简单架构:#
传统服务器架构流程:
1)浏览器通过DNS-server,域名解析到ip
2)浏览器通过ip访问web-server
3)web-server处理访问数据库数据处理数据并返回到浏览器
如图:
我们常规小型项目可能如上图一样只有一台web服务器加上一台数据库服务器,有的甚至只有一台服务器,所有的web服务,缓存服务,数据库服务,上传下载服务等等全都放在一台服务器上面,这样缺陷显然很明显
1:单台服务器面对大量请求和高并发场景会有性能问题;
2:服务一但挂掉会使所有的功能都将无法使用;
3:单台服务器不便于多人维护;
4:单台服务直接暴露后台服务器IP安全也会相对较差
所以需要使用到负载均衡来多个服务器分摊请求和处理上面一系列问题
2 常见的实现负载均衡方案#
2.1 DNS轮询实现负载均衡#
那我们可以在上面的服务器架构做一些简单的优化:用DNS轮询实现简单的负载均衡,具体操作如下
1)浏览器通过DNS-server,域名解析到ip,这一步我们可以给DNS-server添加多条解析记录绑定多个服务器IP,然后通过配置记录的权重来实现负载均衡
2)浏览器通过ip访问web-server
3)web-server处理访问数据库数据处理数据并返回到浏览器
如图:
具体实际操作我们以腾讯云服务器为例,我们先添加两条主机记录
然后我们在负载均衡界面配置权重,这样我们就完成了通过DNS轮询来实现负载均衡,有一点需要注意的是:同记录类型、同主机记录、同线路的记录才可以实现解析的负载均衡
DNS轮询实现负载均衡的优缺点:
优点:
- 零成本:只是在DNS服务器上绑定几个A记录,域名注册商一般都免费提供解析服务;
- 部署简单:就是在网络拓扑进行设备扩增,然后在DNS服务器上添加记录。
缺点:
- 可靠性低:假设一个域名DNS轮询多台服务器,如果其中的一台服务器发生故障,那么所有的访问该服务器的请求将不会有所回应,这是任何人都不愿意看到的。即使从DNS中去掉该服务器的IP,但在Internet上,各地区电信、网通等宽带接入商将众多的DNS存放在缓存中,以节省访问时间,DNS记录全部生效需要几个小时,甚至更久。所以,尽管DNS轮询在一定程度上解决了负载均衡问题,但是却存在可靠性不高的缺点。
- 负载分配不均匀(有,但不会有那么大的影响):DNS负载均衡采用的是简单的轮询算法,不能区分服务器的差异,不能反映服务器的当前运行状态,不能做到为性能较好的服务器多分配请求,甚至会出现客户请求集中在某一台服务器上的情况。DNS服务器是按照一定的层次结构组织的,本地DNS服务器会缓存已解析的域名到IP地址的映射,这会导致使用该DNS服务器的用户在一段时间内访问的是同一台Web服务器,导致Web服务器间的负载不均匀。此外,用户本地计算机也会缓存已解析的域名到IP地址的映射。当多个用户计算机都缓存了某个域名到IP地址的映射时,而这些用户又继续访问该域名下的网页,这时也会导致不同Web服务器间的负载分配不均匀。负载不均匀可能导致的后果有:某几台服务器负荷很低,而另几台服务器负载很高、处理缓慢;配置高的服务器分配到的请求少,而配置低的服务器分配到的请求多。
- 暴露了太多的外网ip
通过上面的DNS轮询实现负载均衡是不是对负载均衡这一概念有了简单的理解,但是我们可以看到DNS轮询实现负载均衡有很多的缺点,那么我们还有其他的负载均衡方案吗?
2.2 nginx反向代理实现负载均衡#
首先需要搞懂什么是反向代理,可以参考我之前写的这篇文章里面的相关资料:https://www.cnblogs.com/ruanraun/p/agent.html
具体流程:
1)浏览器通过DNS-server,域名解析到代理服务器IP
2)浏览器通过ip访问代理服务器web-server
3)代理服务器web-server根据配置文件分发请求给实际真实的后端服务器
4) 后端实际web-server处理访问数据库数据处理数据并返回到代理服务器,最后通过代理服务器返回给浏览器
反向代理实现负载均衡的优缺点:
优点:
1)DNS-server不需要动
2)负载均衡:通过nginx来保证
3)只暴露一个外网ip,nginx->tomcat之间使用内网访问
4)扩容实时:nginx内部可控,随时增加web-server随时实时扩容
5)能够保证站点层的可用性:任何一台tomcat挂了,nginx可以将流量迁移到其他tomcat
缺点:
1)时延增加+架构更复杂了:中间多加了一个反向代理层
2)反向代理层成了单点,非高可用
3)负载能力受服务器本身性能的影响,所有请求响应都需要经过负载均衡服务器,集群最大吞吐量受限于负载均衡服务器网卡带宽,性能越好,负载能力越大。
4)通过代理服务器返回请求结果而不是实际服务器直接返回请求结果也会有性能上的损耗
2.3 LVS调度实现负载均衡#
LVS与nginx在处理请求上面的区别,如下:
LVS:Linux 虚拟机、流量调度,负载均衡
单向的 End user -----> LVS ----->应用集群web-server(如 tomcat或IIS) -----> End user
nginx:高性能代理服务器,系统内部流量分发,反向代理
有来回 End user -----> Ngnix -----> 应用集群web-server(如 tomcat或IIS) -----> Ngnix -----> End user
由于请求处理流程的简化,LVS直接将请求结果返回给客户端而不是像nginx还要返回给代理服务器然后再返回给客户端,所以同量级别的服务器和带宽LVS抗负载能力肯定是比nginx是要强的
下面是 LVS DR模式直接路由实现负载均衡
在通信协议的数据链路层修改mac地址,进行负载均衡。
数据分发时,不修改ip地址,只修改目标mac地址,配置真实物理服务器集群所有机器虚拟ip和负载均衡服务器ip地址一致,达到不修改数据包的源地址和目标地址,进行数据分发的目的。
实际处理服务器ip和数据请求目的ip一致,不需要经过负载均衡服务器进行地址转换,可将响应数据包直接返回给用户浏览器,避免负载均衡服务器网卡带宽成为瓶颈。
LVS的优缺点
优点:
- 配置性低,这里的配置性低不是配置简单,而是一旦配置好之后不会经常去动它,这通常是一大劣势同时也是一大优势,因为没有太多的可配置的选项,所以除了增减服务器,并不需要经常去触碰它,大大减少了人为出错的几率
- 工作稳定,因为其本身抗负载能力很强,所以稳定性高也是顺理成章的事,另外各种 LVS 都有完整的双机热备方案,所以一点不用担心均衡器本身会出什么问题,节点出现故障的话,LVS 会自动判别,所以系统整体是非常稳定的
- 无流量,LVS 仅仅分发请求,而流量并不从它本身出去,所以可以利用它这点来做一些线路分流之用。没有流量同时也保住了均衡器的 IO 性能不会受到大流量的影响
- LVS 基本上能支持所有应用,因为 LVS 工作在第 4 层,所以它可以对几乎所有应用做负载均衡,包括 http、数据库、聊天室等
缺点:
- 安装配置是比nginx复杂
- 对网络依赖性高,所以很多配置失败一般都是网络的问题
- 如果仅仅使用 lvs 作为负载均衡的话,一旦后端接受到请求的服务器出了问题,那么这次请求就失败了,不能像nginx那样流量迁移
- nginx 工作在网络的第 7 层,可以作为网页静态服务器,而LVS工作在网络的第 4 层,固不能针对上层协议分析,处理请求场景比相对nginx少,没有nginx灵活
2.4 负载均衡器硬件实现负载均衡#
直接在服务器和外部网络间安装负载均衡硬件设备,这种设备我们通常称之为负载均衡器。由专门的设备完成,独立于操作系统,整体性能得到大量提高,加上更多的负载均衡策略,智能化的流量管理,可达到最佳的负载均衡需求。 一般来说,硬件负载均衡在功能、性能上优于软件方式,不过成本昂贵,几十万到上百万不等,适合不差钱的土豪公司,很常见的有 F5负载均衡器:
通过F5平衡负载的去访问服务器群的每台机器。访问过程如下图所示
硬件实现负载均衡优缺点:
优点:能够直接通过智能交换机实现,处理能力更强,性能应该是最优的,而且与系统无关,负载性能强更适用于一大堆设备、大访问量、简单应用
缺点:成本高,贵贵贵,重要的事情说三遍,几十万甚至几上百万对于一些一个项目做下来还挣不到这么多钱的小型企业来说也不是小数目,除设备价格高昂之外,它的配置相对复杂冗余,而且很难想象后面服务器做一个集群,但最关键的负载均衡设备却是单点配置;无法有效掌握服务器及应用状态,硬件负载均衡,一般都不管实际系统与应用的状态,而只是从网络层来判断,所以有时候系统处理能力已经不行了,但网络可能还来得及反应(这种情况比较典型,比如应用服务器后面内存已经占用很多,但还没有彻底不行,如果网络传输量不大就未必在网络层能反映出来)
上面总结这这么多负载均衡的处理方案,貌似都有各自的优点和缺点,那么就没有最优解吗?
3 混合型负载均衡
最优解就是把上面的负载均衡方案混合起来,由于多个服务器群内硬件设备、各自的规模、提供的服务等的差异,可以考虑给每个服务器群采用最合适的负载均衡方式,然后又在这多个服务器群间再一次负载均衡或群集起来以一个整体向外界提供服务(即把这多个服务器群当做一个新的服务器群),从而达到最佳的性能。将这种方式称之为混合型负载均衡。
我们可以根据自己开发的实际情况合理的进行混合方案
如图是混合型负载均衡的一种:
流程:
1)通过DNS轮询来线性扩展入口lvs层的性能
2)通过keepalived来保证高可用
3)通过lvs来扩展多个nginx
4)通过nginx负载均衡,业务七层路由,来分发请求,最大限度的提高单次请求的成功率;
总结:
对于上面的混合型负载型均衡虽然厉害:高可用、扩展性、反向代理+扩展均衡,但是维护成本也是极高的,还需要大量的人力和财力,所以我们在构建项目的需要考虑自己公司的实际情况合理的选择配置方案。
基础扩展:#
负载均衡算法决定了后端的哪些健康服务器会被选中。下面是几个常用的算法,这里只是简单介绍,不具体研究其算法实现了:
- 轮询:为第一个请求选择健康池中的第一个后端服务器,然后按顺序往后依次选择,直到最后一个,然后循环。
- 最小连接:优先选择连接数最少,也就是压力最小的后端服务器,在会话较长的情况下可以考虑采取这种方式。
- 散列:根据请求源的 IP 的散列(hash)来选择要转发的服务器。这种方式可以一定程度上保证特定用户能连接到相同的服务器。如果你的应用需要处理状态而要求用户能连接到和之前相同的服务器,可以考虑采取这种方式。
参考相关文章
实战配置和nginx的请求原理学习
https://www.cnblogs.com/jiekzou/p/4486447.html
LVS相关资料
硬件负载均衡:F5之LTM实现流程及操作 - 知乎
负载均衡介绍: 负载均衡详解 - 腾讯云开发者社区-腾讯云
浅谈Nginx负载均衡与F5的区别:http://www.ideadata.com.cn/wisdomAction/readWisdom.do?id=75
有软件负载均衡,也有硬件负载均衡,选择哪个: 有软件负载均衡,也有硬件负载均衡,选择哪个? - 腾讯云开发者社区-腾讯云
腾讯云负DNS载均衡设置权重: DNS 解析 DNSPod DNS 解析配置负载均衡-操作指南-文档中心-腾讯云