这是我参与8月更文挑战的第19天,活动详情查看:8月更文挑战
一、前言
负载均衡架构,主流是 LVS+KeepAlived+Nginx 这一套架构。
Java工程师了解即可。
LVS说白了就是一种负载均衡的技术,部署在 Linux 服务器上,LVS 服务器获取到100个请求,均匀分发给2台部署在 Linux 服务器上的 Tomcat(Web服务器),每台 Web 服务器拿到 50 个请求就可以了。
LVS 原理:
- 首先用户向负载均衡器调度器(
Director Server)发起请求,负载均衡器将请求发往至内核空间,交给内核模块进行检测。 - 内核模块中的
PREROUTING链首先会收到用户请求,判断目标地址是否是负载均衡器的IP地址,如果是,则将数据包发往INPUT链。 IPVS模块是工作在INPUT链上的,当用户请求到达INPUT链上时,IPVS会将用户请求和自己已定义好的集群服务作对比,如果用户请求的就是定义的集群服务,那么IPVA会强行修改数据包里的目标IP地址和目标端口,并将新的数据包发往POSTROUTING链。POSTROUTING链接收到数据包发现目标IP地址刚好是自己的后端的服务器,那么通过选路,将数据包最终发送给后端的服务器。
LVS 组成,主要为两部分:
ipvs(ip virtual server):即ip虚拟服务,是工作在内核空间上的一段代码,主要是实现调度的代码。ipvsadm:工作在用户空间,负责为ipvs内核框架编写规则,定义谁是集群服务,谁是后端真实服务器。
LVS 术语:
DS(Director Server):目标服务器,即负载均衡器。RS(Real Server):真实服务器,即后端服务器。VIP(virtual IP):是外部直接面向用户请求,作为用户请求的目标IP地址。DIP(Director Server IP):主要用于和内部主机通信的IP地址。RIP(Real Server IP):真正服务端IPCIP(Client IP):客户端IP
二、LVS 架构
先来了解下简单的用户请求,如图:
- 用户在浏览器访问网站,发送请求会指定一个域名,域名得到
DNS中做解析成IP地址(可以是LVS服务器的IP地址) LVS服务器,作为负载均衡调度器,直接基于Linux内核内部的一些底层机制进行请求转发,主要基于Linux内核级的一些底层机制做请求转发Web服务器接收请求:一般是Tomcat,4核8G的服务器每秒 1000 以内的请求
LVS(Linux Virtual Server) :Linux 虚拟服务器,说白了就是把一组 Web 服务器统一成一台虚拟机服务器对外提供服务,访问都经过 LVS,就跟一台服务器一般。
LVM是基于Linux内核级的一些底层机制做请求转发,所以效率极高,单机抗每秒几十万甚至上百万吞吐量。
1)异地多机房多活 LVS 集群部署架构
举个栗子:公司系统的机房在国内,北京。
那么在美国或者欧洲的人来访问这个站点:通过
DNS进行域名解析,拿到IP,对应到机房内的某台服务器。 这时候他的网络请求,可能从国外走各种网络转发,一路转发到国内的机房里的一台服务器上,通常是比较慢的。 如果直接访问国外的站点,那就比较快了。
这时候,一般都会做异地多机房多活的 LVS 集群部署。
假设是国际化的站点,实际上就是在国内部署一个机房、美国部署一个机房、德国部署一个机房等,这些机房之间都部署了同样的数据存储,互相之间需要进行数据交换和同步。
即,所有核心数据都必须在不同地区的机房之间进行同步,才能保证不同地区的用户看到一样的内容。
然后网站共享一个虚拟 IP 地址:访问的时候,中国的用户解析虚拟 IP 地址后会把请求路由到国内的机房里,国外的用户会路由到距离自己比较近的机房。
(2)基于 NAT 技术实现的 LVS 请求转发原理
谨记:LVS 是工作在四层网络协议上的负载均衡的技术,Nginx 是工作在七层网络协议上的负载均衡的技术。
第四层的网络协议就是
TCP/IP协议,第七层的网络协议就是HTTP协议。
你可能以为的过程是:
- 客户端与
LVSTCP三次握手后,建立连接 - 把
HTTP请求报文发送给LVS LVS再把请求报文转发为Web服务器
实际上这是错误的。 LVS 工作在四层协议上(传输层),而 HTTP 是在七层协议上(应用层)。
实际的过程如下:
- 客户端与
LVSTCP三次握手后,建立连接 - 客户端发送请求,
Linux服务器拿到报文后 - 由
Linux内核转交给LVS的核心代码模块 LVS核心代码模块会根据负载均衡算法从后端Web服务器集群里挑选出一台机器,用于把报文转发给Web服务器
LVS负载均衡系统核心代码是挂载在Linux内核层里的。
- 用
NAT技术改写报文里面的目标地址和端口,改为Web服务器的地址和端口 - 此时
LVS会把这个(客户端的Socket连接,Web服务器) 记录到Hash表里
这样,下次同一个
Socket连接再发送报文,就直接转发到对应的Web服务器中
- 发送报文
最后一小点,Web服务器读取的是完整的 HTTP 请求。
例如,
Tomcat本身就是针对七层网络协议里的应用层的HTTP协议。
小小总结下:
客户端会与 LVS 集群(包括 LVS、real server)进行 TCP 连接,但是 LVS 服务器不会与 real server 再建立一次 TCP 连接,只会转发 TCP 报文:
NAT模式: 原理是修改IP报文的地址和TCP报文的端口,然后转发数据包,没有TCP连接行为,但是客户相信它们连接一个IP地址,而不同IP地址的服务器组也认为它们是与客户直接相连的。FULLNAT模式: 原理也是修改IP报文的地址和TCP报文的端口,然后转发数据包,没有TCP连接行为,但是转发的时候更既改了源地址也改了目标地址,所以从客户端看是和LVS建立的连接,从后端看也是和LVS建立了连接DR模式: 原理是修改请求的mac地址(二层),然后转发数据包,没有TCP连接行为IP隧道模式:LVS和real server走的是IP隧道技术, 没有与real server建立TCP连接
3)基于 IP 隧道技术的 LVS 请求与响应分离原理
问题:Web服务器如何响应请求?如何返回数据?
最容易想到的是,怎样来的,那就怎样回去呗,直接再走 LVS 呗,然而:
LVS最早在实现的时候经过压测,如果所有的响应报文都依然从LVS来走。 如果Web服务器达到20台以上的时候,往往整体的每秒QPS都达到了几万了,此时LVS调度服务器的吞吐量会达到极限,成为一个瓶颈,主要是LVS服务器得处理请求,还得获取响应返回,最起码是他的网络带宽可能就吃不消了。
事实上,大部分的请求里的数据较少,响应的数据很多。
那能不能让 LVS服务器处理请求,但让 Web 服务器直接把响应返回到客户端里呢? 那就是 IP 隧道技术:IP tunneling,也叫 IP 封装技术。
LVS拿到请求之后,把目标地址为Web服务器的VIP的请求报文封装到另外一个IP报文里,转发此报文给一台Web服务器,Web服务器解析报文时候,发现目标地址为VIP,结果这个VIP配置在自己的IP隧道设备上,那此时就可以处理这个请求。