1. 4层负载和7层负载
所谓四层就是基于IP+端口
的负载均衡;七层就是基于URL等应用层信息的负载均衡;同理,还有基于MAC地址的二层负载均衡和基于IP地址的三层负载均衡。 换句换说,二层负载均衡会通过一个虚拟MAC地址接收请求,然后再分配到真实的MAC地址;三层负载均衡会通过一个虚拟IP地址接收请求,然后再分配到真实的IP地址;四层通过虚拟IP+端口
接收请求,然后再分配到真实的服务器;七层通过虚拟的URL或主机名接收请求,然后再分配到真实的服务器。
所谓的四到七层负载均衡,就是在对后台的服务器进行负载均衡时,依据四层的信息或七层的信息来决定怎么样转发流量。 比如四层的负载均衡,就是通过发布三层的IP地址(VIP),然后加四层的端口号,来决定哪些流量需要做负载均衡,对需要处理的流量进行NAT处理,转发至后台服务器,并记录下这个TCP(UDP)的流量是由哪台服务器处理的,后续这个连接的所有流量都同样转发到同一台服务器处理。七层的负载均衡,就是在四层的基础上(没有四层是绝对不可能有七层的),再考虑应用层的特征,比如同一个Web服务器的负载均衡,除了根据VIP加80端口辨别是否需要处理的流量,还可根据七层的URL、浏览器类别、语言来决定是否要进行负载均衡。举个例子,如果你的Web服务器分成两组,一组是中文语言的,一组是英文语言的,那么七层负载均衡就可以当用户来访问你的域名时,自动辨别用户语言,然后选择对应的语言服务器组进行负载均衡处理。
负载均衡器通常称为四层交换机或七层交换机。四层交换机主要分析IP层及TCP/UDP层,实现四层流量负载均衡。七层交换机除了支持四层负载均衡以外,还有分析应用层的信息,如HTTP协议URI或Cookie信息。
4层负载即在OSI第4层工作,就是TCP层啦。此种Load Balance不理解应用协议(如HTTP/FTP/MySQL等等)。4层负载最常见的是:LVS,F5。
7层负载即OSI的最高层:应用层。此时,该Load Balancer能理解应用协议。例子: haproxy,MySQL Proxy。7层负载最常见的的是:nginx,各种网关也算。
最后总结:4层负载和7层负载的特性都是其所在的OSI层次位置决定的。4层只有TCP,而TCP只是规定了数据如何传输,所以4层负载时看不到数据是什么样的,只能控制数据包往哪个RIP转发。但是也正因为4层的TCP如此简单,所以4层负载的性能要比7层高。 而7层负载在应用层, 这个层面其实就是应用程序了,既然它是应用程序就能各种分析解析传输的是什么数据,所以7层负载的功能性更强,但是想对比4层而言性能上就弱了许多。
2. LVS的调度算法
4种静态调度方式
rr: 轮询(round-robin)
wrr: 加权轮询(weight round-robin)
sh: 原地址哈希(source hash)
dh: 目标地址哈希(destination hash)
动态调度方式活动连接
:表示用户已经连接到服务器,并且正在数据传输。非活动连接
:表示已经和服务器建立连接,并且数据已经传输结束,但是还没有断开连接,
如有长连接。对于活动连接因为有数据交换,所以会占用更多的内存;非活动连接只要维护当前会话状态即可,因此需要很小的内存空间(最多几十KB)。
因此要在调度时考虑服务器当前的负载情况,需要区别对待活动连接和非活动连接,甚至可以忽略非活动连接(因为占用很少资源)。
动态调度算法就是根据后端服务器当前的活动连接和非活动连接数来实现请求的调度。动态调度算法常见的有如下几种:
- LC:最少连接算法(LeastConnection)
- WLC:**加权最少连接(Weight Least Connection)**
- SED: **最短期望延迟 Shortest Expected Delay**
- NQ:**永不排队(Never Queue)**
- LBLC:**基于本地的最少连接 Locality-Based Least-Connection**
- LBLCR:**基于本地的带有复制功能的最少连接调度算法 Locality-Based Least Connections withReplication**
- LC
最少连接算法(LeastConnection) 。 通过计算后端服务器当前的活动连接数和非活动连接数的总数,并对多个节点的结果进行比较来决定将请求转发到哪个节点,哪个节点的值最小就将请求转发到哪个节点。因此这种算法会考虑到每个服务器节点当前的连接数,并挑选一个连接数最小(相对最空闲)的节点进行请求转发。
具体算法:连接数=活动连接数*256 + 非活动连接数
- WLC
加权最少连接(Weight Least Connection)。 因为每个服务器节点的性能可能不同,因此需要性能高的服务器负担更多的请求,所以在最少连接算法的基础上结合服务器节点的权重来进行请求调度。
计算方式:结果=(活动连接数*256 + 非活动连接数)/权重
这里的权重值,一般要结合当前节点在集群环境中性能比例来计算。例如A、B两个节点的性能为2:1,那么它们的权重值也要保持2:1。
通过以上的计算,取结果最小值的那个节点作为处理当前请求的目标节点。
- SED
最短期望延迟 Shortest Expected Delay
WLC调度算法有一定的缺陷。当请求量比较少的时候,该算法的计算结果是将请求更多的指向了权重低的服务器,即性能较差的服务器;而我们
希望在请求少的时候将请求尽可能转发到性能高的服务器上。sed这种调度算法为了解决WLC的缺点而生,它不再考虑非活动连接。这种算法在请求
量较少的时候也能实现类似加权轮询调度的效果。
算法: (活动连接数+1)*256/权重
sed这种算法也有一定缺陷,在请求量比较少的时候,某个权重下的节点可能一个请求都没有轮到,而权重大的节点却轮到了比较多的请求。
因此出现了下一种动态调度算法:NQ。
- NQ
永不排队(Never Queue)
这种算法在请求量比较小的时候可以避免sed算法存在的问题,也就是会将请求在sed的结果上进行轮询调度。例如sed算法的结果当前已经
将请求有转发到A、B节点,新的请求又被计算到A节点,此时如果有C节点,则NQ算法会将这个新的请求调度到C节点而不是继续调度到A节点而
不会理会此时A的权重问题,权重的判断仅仅在sed算法这个步骤进行考虑。也就是NQ算法在sed算法的结果之后增加了轮询的机制(也会考虑一定程度的权重),
因此这种算法就会尽量不然请求出现排队的情况,即避免了某个节点非常繁忙而其他节点相对空闲的情况。避免了权重小的节点不会出现没有请求被调度的情况。
- LBLC
基于本地的最少连接 Locality-Based Least-Connection
这种算法本质就是LC算法或理解为WLC算法。但是该算法的特性是,注意实现目标是要和静态调度算法中的DH算法一样,用于将同一类请求
转发到一个固定节点,因此常用于缓存服务器的场景。但是DH算法因为是静态调度算法,不会考虑后端(缓存)服务器的当前连接数,但LBLC就
是在DH算法的基础上考虑后端服务器当前的连接数。
如果(缓存)服务器使用了集群(如Memcached的主主复制),因为所有节点的缓存数据都相同,因此要使用负载均衡算法来实现请求按照当
前服务器的负载进行转发。而如果后端的每个缓存服务器的内容不同,使用LBLC就会破坏命中率并且导致多个缓存节点缓存了相同的数据,因此为了
提高缓存命中率以及防止多个节点缓存相同的数据,一般就不采用LBLC而直接采用DH。
所以,要提高负载均衡效果就要破坏缓存命中率以及多个缓存节点会缓存相同数据;要提高缓存命中率已经防止多个节点缓存相同的数据,就会降低负载均衡效果。所以这需要找到一个平衡点,根据实际需要来决定。
- LBLCR
基于本地的带有复制功能的最少连接调度算法 Locality-Based Least Connections withReplication
**
为了解决LBLC算法的缺陷,即提高缓存命中率且防止多个缓存节点缓存相同数据,并且保证负载均衡效果。就需要使用这里的调度算法。
LBLC就是一个DH+LC的算法,并不会考虑缓存命中率而只考虑尽可能的负载均衡。LBLCR这种算法中,了可以理解为后端多个缓存服务器
可以通过内容交换协议实现缓存共享。因此无论请求哪个缓存节点,如果该节点没有数据,它不会直接到Web服务器上查询,而是试图到另一个
缓存节点中查询,如果有则将其拿过来并放入当前的缓存服务器,这样就实现一定程度的缓存复制功能,可以提高缓存命中率。
注意,这里的缓存共享并不是完全的Replication,而是仅仅当请求的节点没有需要的数据时去其他缓存节点查询所请求的缓存数据。但是这种
机制因为要到其他缓存节点查询,所以性能会比直接使用DH差一些。
这种算法也不会防止多个节点缓存相同的数据,而只能保证缓存命中率。
4. 搭建LVS集群DR模型
4.1 隐藏VIP方法(对外隐藏,对内可见):
修改内核参数:
arp协议规定:目标mac地址为FF:FF:FF:FF:FF:FF
时交换机触发广播。
cd /proc/sys/net/ipv4/conf/*lF*/
arp_ignore
:定义接收到ARP请求时的响应级别;
0: 只要本地配置的有相应地址,就给予响应。 默认级别。
1∶ 仅在请求的目标(MAC)地址配置请求到达的接口上的时候,才给予响应;arp_announce
:定义将自己地址向外通告时的通告级别;
0: 将本地任何接口上的任何地址向外通告;
1: 试图仅向目标网络通告与其网络匹配的地址。默认级别。
2: 仅向与本地接口上地址匹配的网络进行通告;
4.2 整体环境
由于需要多个linux服务器。我在本机上使用VMware装了4个虚拟机,分别起名为
node01
: 192.168.235.130(主LVS)node02
: 192.168.235.131(real_server)node03
: 192.168.235.132(real_server)node04
: 192.168.235.133(备LVS)
除此之外在VMware我选择的使用NAT模式,所以VMware会在我们的系统里面创建一个虚拟网卡来专门处理本机和虚拟机里面的linux系统通讯用的,linux里面的机器能联网也是通过这块虚拟网卡实现的。这块虚拟网卡的叫做:VMware Network Adapter VMnet8:
它的ip是:192.168.235.1
整体网路拓扑图如下:
4.3 linux开放某个端口
查看防火墙某个端口是否开放
firewall-cmd --query-port=80/tcp
开放防火墙端口80
firewall-cmd --zone=public --add-port=80/tcp --permanent
关闭80端口
firewall-cmd --zone=public --remove-port=80/tcp --permanent
配置立即生效
firewall-cmd --reload
查看防火墙状态
systemctl status firewalld
关闭防火墙
systemctl stop firewalld
打开防火墙
systemctl start firewalld
开放一段端口
firewall-cmd --zone=public --add-port=8121-8124/tcp --permanent
查看开放的端口列表
firewall-cmd --zone=public --list-ports
4.4 配置real_server (node02和node03)
- 确保开放80端口
- 修改内核arp协议
查看本机网卡标记ifconfig
:
可以看到我的网卡的标记是ens33
。所以需要修改/proc/sys/net/ipv4/conf/ens33/
和/proc/sys/net/ipv4/conf/all/
下面的arp_ignore
和 arp_announce
文件。
echo 1 > /proc/sys/net/ipv4/conf/ens33/arp_ignore;
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore;
echo 2 > /proc/sys/net/ipv4/conf/ens33/arp_announce;
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce;
确保修改成功我们需要查看文件内容:
cat /proc/sys/net/ipv4/conf/ens33/arp_ignore /proc/sys/net/ipv4/conf/all/arp_ignore /proc/sys/net/ipv4/conf/ens33/arp_announce /proc/sys/net/ipv4/conf/all/arp_announce
结果:
1 1 2 2
- 新增环形网卡,设置隐藏的vip
注意:
- 一定是修改了arp协议文件后再新增回环网卡,如果不修改arp协议的话新增回环网卡会被广播出去,这样就无法隐藏vip了。
- 这里的掩码地址必须是
255.255.255.255
ifconfig lo:3 192.168.235.100 netmask 255.255.255.255
ifconfig
- 安装
httpd
软件并启动
安装完成后启动yum install httpd -y
新增index.html文件并写入内容service httpd start
node02节点:
node03节点:echo node02@192.168.235.131 > /var/www/html/index.html
echo node03@192.168.235.132 > /var/www/html/index.html
启动成功后在浏览器查看node1和node2的地址:
real_server:node01 和 node02 节点配置成功。
4.4 配置LVS (node01)
- 确保开放80端口
新增虚拟网卡
ifconfig ens33:8 192.168.235.100/24
或者
ifconfig ens33:8 192.168.235.100 netmask 255.255.255.0
查看配置后的信息:
安装ipvsadm
yum install ipvsadm -y
配置ipvsadm
ipvsadm -A -t 192.168.235.100:80 -s rr
ipvsadm -a -t 192.168.235.100:80 -r 192.168.235.131 -g -w 1
ipvsadm -a -t 192.168.235.100:80 -r 192.168.235.132 -g -w 1
ipvsadm -ln
配置之后查看配置效果:
启动ipvsadm
service ipvsadm start
验证
打开浏览器输入: 192.168.235.100 疯狂F5。
- 查看node01的网卡信息:
ifconfig
- 查看ipvsadm的偷窥记录:
ipvsadm -lnc
5. 搭建LVS高可用集群keepalived
5.1清理node01节点
清理方式有2种:
第1种方式:重装系统后开放80端口。
第2种方式:
- 清理ipvsadm:
ipvsadm -C
- 关闭网卡信息:
ifconfig ens33:8 down
5.2 配置LVS主 (node01)
安装 keepalived 和 ipvsadm
yum install ipvsadm keepalvied -y
配置keepalived
cd /etc/keepalived/
cp keepalived.conf keepalived.conf.bak
```powershell
虚拟路由冗余协议
vrrp_instance VI_1 { state MASTER #表示主 interface ens33 #网卡标记 virtual_router_id 51 #所属id priority 100 #主从权重值, 权重值越大的会在下一次被选为主。 advert_int 1 authentication { #认证信息
auth_type PASS
auth_pass 1111
} virtual_ipaddress { #负载地址
192.168.235.100/24 dev ens33 label ens33:8
} }
虚拟服务配置
virtual_server 192.168.235.100 80 { delay_loop 6 lb_algo rr #负载方式 rr 轮询 lb_kind DR #路由模式:直接路由。 persistence_timeout 0 #回话超时时间:生产不能为0, 测试rr方式看效果需要是0 protocol TCP #网络协议:TCP
# 真实后端服务
real_server 192.168.235.131 80 { #服务地址 端口
weight 1 #权重
HTTP_GET { #HTTP_GET
url {
path /
status_code 200
}
connect_timeout 3
retry 3
delay_before_retry 3
}
}
# 真实后端服务
real_server 192.168.235.132 80{ √
weight 1 #权重
HTTP_GET { #HTTP_GET
url {
path /
status_code 200
}
connect_timeout 3
retry 3
delay_before_retry 3
}
} }
3. 启动keepalived
```powershell
service keepalived start
- 验证
打开浏览器输入: 192.168.235.100 疯狂F5。
- 查看node01的网卡信息:
ifconfig
- 查看ipvsadm
- 查看ipvsadm的偷窥记录:
ipvsadm -lnc
5.3 配置LVS备 (node04)
- node04开放80端口:查看4.3查看如何开放 ==>>>>>>
在node04上安装keepalived 和 ipvsadm
yum install ipvsadm keepalvied -y
从
node01
把keepalived.conf
文件复制到node04
在node01
上执行命令:
cd /etc/keepalived/
scp ./keepalived.conf root@192.168.235.133:`pwd`
进入
node04
编辑keepalived.conf
cd /etc/keepalived/
vim ./keepalived.conf
修改配置keepalived.conf
state 改为 BACKUP priority 改为低于100的, 比如改为50
## 虚拟路由冗余协议
vrrp_instance VI_1 {
state BACKUP #表示备
interface ens33 #网卡标记
virtual_router_id 51 #所属id
priority 50 #主从权重值, 权重值越大的会在下一次被选为主。
advert_int 1
authentication { #认证信息
auth_type PASS
auth_pass 1111
}
virtual_ipaddress { #负载地址
192.168.235.100/24 dev ens33 label ens33:8
}
}
## 虚拟服务配置
virtual_server 192.168.235.100 80 {
delay_loop 6
lb_algo rr #负载方式 rr 轮询
lb_kind DR #路由模式:直接路由。
persistence_timeout 0 #回话超时时间:生产不能为0, 测试rr方式看效果需要是0
protocol TCP #网络协议:TCP
# 真实后端服务
real_server 192.168.235.131 80 { #服务地址 端口
weight 1 #权重
HTTP_GET { #HTTP_GET
url {
path /
status_code 200
}
connect_timeout 3
retry 3
delay_before_retry 3
}
}
# 真实后端服务
real_server 192.168.235.132 80{ √
weight 1 #权重
HTTP_GET { #HTTP_GET
url {
path /
status_code 200
}
connect_timeout 3
retry 3
delay_before_retry 3
}
}
}
启动keepalived
service keepalived start
查看网卡信息:
查看ipvsadm:测试。
浏览器输入192.168.235.199 疯狂F5。 没问题。
关闭node01的网卡:
ifconfig ens33 down
回浏览器继续疯狂F5,可以发现服务没出现问题。
去node04 查看网卡信息: ifconfig
发现新增了一个虚拟网卡,说明node04备顶上来了。
打开VMware重启一下node01.
开放80端口。启动keepalived。
回浏览器继续疯狂F5,可以发现服务没出现问题。
在node01上看网卡信息:ifconfig
发现ens33:8 网卡又从node04回来了。说明node01又变回了主,node04又变回了备。浏览器请求没有受到任何影响。