[svc]高并发场景 LVS DR +KeepAlive高可用实现及ka的persistence_timeout参数
LVS-DR+keepalived模式是一种非常经典的常用生产组合
高可用场景及LVS架构
一般都用一(负载)拖多(Server Array)方式
使用LVS架设的服务器集群系统有三个部分组成:
(1)最前端的负载均衡层,用Load Balancer表示;
(2)中间的服务器集群层,用Server Array表示;
(3)最底端的数据共享存储层,用Shared Storage表示;
在用户看来,所有的内部应用都是透明的,用户只是在使用一个虚拟服务器提供的高性能服务。
系统环境准备
系统环境
- 采用4台cenos7.4来做实验
DS:Director Server。指的是前端负载均衡器节点。
RS:Real Server。后端真实的工作服务器。
- 将selinux和防火墙关掉
[root@n1 ~]# cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)
[root@n1 ~]# uname -a
Linux lb03 3.10.0-693.el7.x86_64 #1 SMP Tue Aug 22 21:09:27 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
[root@n1 ~]# systemctl status firewalld.service
● firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
Active: inactive (dead)
Docs: man:firewalld(1)
[root@n1 ~]# getenforce
Disabled
- web节点准备(两台nginx)
[root@n1 ~]# curl 192.168.14.13
web03
[root@n1 ~]# curl 192.168.14.14
web04
- 安装lvs的命令行管理软件ipvsadm
yum -y install ipvsadm
ipvsadm # 激活lvs内核模块
lsmod|grep ip_vs # 查看模块是否加载
lvs介绍和ipvsadm与ipvs的关系
早在2.2内核时, IPVS就已经以内核补丁的形式出现。
从2.4.23版本开始,IPVS软件就合并到Linux内核的常用版本的内核补丁的集合。
从2.4.24以后IPVS已经成为Linux官方标准内核的一部分。(uname -r)
- LVS无需安装
- 安装的是管理工具,第一种叫ipvsadm,第二种叫keepalive
- ipvsadm是通过命令行管理,而keepalive读取配置文件管理
- 后面我们会用Shell脚本实现keepalive的功能
配置LVS负载均衡服务(在n1操作)
负载节点n1设置
lb上配虚ip -- 清理lvs规则 -- 设置tcp/tcpfin/udp连接timeout -- 添加VIP -- 给VIP挂RS -- 检查
步骤1:在eth0网卡绑定VIP地址(ip)
步骤2:清除当前所有LVS规则(-C)
步骤3:设置tcp、tcpfin、udp链接超时时间(--set)
步骤4:添加虚拟服务(-A),
-t指定虚拟服务的IP端口,
-s 指定调度算法 调度算法见man ipvsadm, rr wrr 权重轮询
-p 指定超时时间
步骤5:将虚拟服务关联到真实服务上(-a)
-r指定真实服务的IP端口
-g LVS的模式 DR模式
-w 指定权重
步骤6:查看配置结果(-ln)
ip addr add 192.168.14.100/24 dev eth0
ipvsadm -C
ipvsadm --set 30 5 60
ipvsadm -A -t 192.168.14.100:80 -s wrr -p 20
ipvsadm -a -t 192.168.14.100:80 -r 192.168.14.13:80 -g -w 1
ipvsadm -a -t 192.168.14.100:80 -r 192.168.14.14:80 -g -w 1
ipvsadm -ln
[root@n1 ~]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.14.100:80 rr persistent 20
-> 192.168.14.13:80 Route 1 0 0
-> 192.168.14.14:80 Route 1 0 0
ipvsadm 参数:
-l --list 显示内核虚拟服务器表
-n --numeric ip和端口以数字形式显示(不以域名)
两台web节点设置
步骤1:修改内核参数抑制ARP响应
步骤2:在lo网卡绑定VIP地址(ip)
- 抑制arp响应
cat >>/etc/sysctl.conf<<EOF
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
EOF
sysctl -p
- 为lo绑定虚vip
ip addr add 192.168.14.100/32 dev lo
- 清空arp表(web节点+负载节点)
ip neigh flush dev eth0
ip neigh flush dev lo
- 测试
curl 192.168.14.100
LVS的模式
DR模式
DR负载均衡模式数据分发过程中不修改IP地址,只修改mac地址,由于实际处理请求的真实物理IP地址和数据请求目的IP地址一致,所以不需要通过负载均衡服务器进行地址转换,可将响应数据包直接返回给用户浏览器,避免负载均衡服务器网卡带宽成为瓶颈。因此,DR模式具有较好的性能,也是目前大型网站使用最广泛的一种负载均衡手段。
lvs使用场景说明:
a)通过在调度器LB上修改数据包的目的MAC地址实现转发。注意,源IP地址仍然是CIP,目的IP地址仍然是VIP。
b)请求的报文经过调度器,而RS响应处理后的报文无需经过调度器LB,因此,并发访问量大时使用效率很高,比Nginx代理模式强于此处。
c)因DR模式是通过MAC地址的改写机制实现转发的,因此,所有RS节点和调度器LB只能在同一个局域网中。需要注意RS节点的VIP的绑定(lo:vip/32)和ARP抑制问题。
d)强调下:**RS节点的默认网关不需要是调度器LB的DIP**,而应该直接是IDC机房分配的上级路由器的IP(这是RS带有外网IP地址的情况),理论上讲,只要RS可以出网即可,不需要必须配置外网IP,但走自己的网关,那网关就成为瓶颈了。
e)由于DR模式的调度器仅进行了目的MAC地址的改写,因此,调度器LB无法改变请求报文的目的端口。LVS DR模式的办公室在二层数据链路层(MAC),NAT模式则工作在三层网络层(IP)和四层传输层(端口)。
f)当前,调度器LB支持几乎所有UNIX、Linux系统,但不支持windows系统。真实服务器RS节点可以是windows系统。
g)总之,DR模式效率很高,但是配置也较麻烦。因此,访问量不是特别大的公司可以用haproxy/Nginx取代之。这符合运维的原则:简单、易用、高效。日1000-2000W PV或并发请求1万以下都可以考虑用haproxy/Nginx(LVS的NAT模式)
h)直接对外的访问业务,例如web服务做RS节点,RS最好用公网IP地址。如果不直接对外的业务,例如:MySQL,存储系统RS节点,最好只用内部IP地址。
DR模式说明:
(a) 当用户请求到达Director Server,此时请求的数据报文会先到内核空间的PREROUTING链。 此时报文的源IP为CIP,目标IP为VIP
(b) PREROUTING检查发现数据包的目标IP是本机,将数据包送至INPUT链
(c) IPVS比对数据包请求的服务是否为集群服务,若是,将请求报文中的源MAC地址修改为DIP的MAC地址,将目标MAC地址修改RIP的MAC地址,然后将数据包发至POSTROUTING链。 此时的源IP和目的IP均未修改,仅修改了源MAC地址为DIP的MAC地址,目标MAC地址为RIP的MAC地址
(d) 由于DS和RS在同一个网络中,所以是通过二层来传输。POSTROUTING链检查目标MAC地址为RIP的MAC地址,那么此时数据包将会发至Real Server。
(e) RS发现请求报文的MAC地址是自己的MAC地址,就接收此报文。处理完成之后,将响应报文通过lo接口传送给eth0网卡然后向外发出。 此时的源IP地址为VIP,目标IP为CIP
(f) 响应报文最终送达至客户端
注意点:
RS:
1.VIP的绑定(lo:vip/32)
2.ARP抑制问题
1.RS不需要将网关指向DR
2.DR不支持端口改写,仅是路由转发.
3.1-2kw的并发用nginx可以搞定,dr模式配置较为麻烦.
结合keepalive实现lb的高可用
- keepalive的作用
1. 添加VIP
2. 添加LVS配置
3. 高可用(VIP漂移)
4. web服务器健康检查
安装keepalive
ipadm -C
yum install keepalive -y
priority 越高越优先成为master
lb-n1配置
root@n1 ~]# cat /etc/keepalived/keepalived.conf
global_defs {
router_id LVS_01
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.14.100/24
}
}
virtual_server 192.168.14.100 80 {
delay_loop 6
lb_algo wrr
lb_kind DR
nat_mask 255.255.255.0
persistence_timeout 50
protocol TCP
real_server 192.168.14.13 80 {
weight 1
TCP_CHECK {
connect_timeout 8
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
real_server 192.168.14.14 80 {
weight 1
TCP_CHECK {
connect_timeout 8
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
}
lb2-n2的配置
root@n2 ~]# cat /etc/keepalived/keepalived.conf
global_defs {
router_id LVS_02
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.14.100/24
}
}
virtual_server 192.168.14.100 80 {
delay_loop 6
lb_algo wrr
lb_kind DR
nat_mask 255.255.255.0
persistence_timeout 50
protocol TCP
real_server 192.168.14.13 80 {
weight 1
TCP_CHECK {
connect_timeout 8
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
real_server 192.168.14.14 80 {
weight 1
TCP_CHECK {
connect_timeout 8
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
}
启动后就ok.
高可用测试: 将n3的nginx关掉, 访问就自动跑到了n4上.
附录: keepalive配置说明
global_defs {
notification_email {
edisonchou@hotmail.com
}
notification_email_from sns-lvs@gmail.com
smtp_server 192.168.80.1
smtp_connection_timeout 30
router_id LVS_DEVEL # 设置lvs的id,在一个网络内应该是唯一的
}
vrrp_instance VI_1 {
state MASTER #指定Keepalived的角色,MASTER为主,BACKUP为备
interface eth1 #指定Keepalived的角色,MASTER为主,BACKUP为备
virtual_router_id 51 #虚拟路由编号,主备要一致
priority 100 #定义优先级,数字越大,优先级越高,主DR必须大于备用DR
advert_int 1 #检查间隔,默认为1s
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.80.200 #定义虚拟IP(VIP)为192.168.2.33,可多设,每行一个
}
}
# 定义对外提供服务的LVS的VIP以及port
virtual_server 192.168.80.200 80 {
delay_loop 6 # 设置健康检查时间,单位是秒
lb_algo wrr # 设置负载调度的算法为wlc
lb_kind DR # 设置LVS实现负载的机制,有NAT、TUN、DR三个模式
nat_mask 255.255.255.0
persistence_timeout 0
protocol TCP
real_server 192.168.80.102 80 { # 指定real server1的IP地址
weight 3 # 配置节点权值,数字越大权重越高
TCP_CHECK {
connect_timeout 10
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
real_server 192.168.80.103 80 { # 指定real server2的IP地址
weight 3 # 配置节点权值,数字越大权重越高
TCP_CHECK {
connect_timeout 10
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
}
keepalived persistence_timeout参数意义 LVS Persistence 参数的作用
persistence_timeout参数
persistence_timeout 300 # 单位秒, 这个参数的意义是保持客户端的请求在这个时间段内全部发到同一个真实服务器。
正常情况下LVS会保证同一个TCP链接数据包会发往同一个真实服务器。
例如:(192.168.80.1:49165 192.168.80.120:8080 192.168.80.136:8080)
LVS会记录这个TCP链接的【原IP与端口,目标IP与端口】,后续的数据包会发送到192.168.80.136:8080
。
但是如果设置了persistence_timeout那么在这个时间段内,当前IP地址下所有的TCP链接数据包都会被发送到同一个真实服务器。假设客户端使用5个端口 建立了5个TCP链接,那么这5个链接会被发往相同的后端服务器,反之亦然。
我们使用命令查看IPVS的规则,可以看到-p 300 已经被设置进去了。
[root@bogon ~]# ipvsadm -S -n
-A -t 192.168.80.120:8080 -s rr -p 300
-a -t 192.168.80.120:8080 -r 192.168.80.135:8080 -i -w 1
-a -t 192.168.80.120:8080 -r 192.168.80.136:8080 -i -w 1
然后客户端请求LVS服务器。我们通过ipvsadm -L -n -c命令查看转发规则。发现所有的TCP链接都指向了一个后端服务器。
我们注意看(TCP 02:36 NONE 192.168.80.1:0 192.168.80.120:8080 192.168.80.136:8080)
就是它记录这当前客户端的IP地址,这样无论后续多少TCP请求都会被发到同一个后端服务器。
TCP 00:16 FIN_WAIT 192.168.80.1:49165 192.168.80.120:8080 192.168.80.136:8080
TCP 00:16 FIN_WAIT 192.168.80.1:49168 192.168.80.120:8080 192.168.80.136:8080
TCP 00:16 FIN_WAIT 192.168.80.1:49169 192.168.80.120:8080 192.168.80.136:8080
TCP 02:36 NONE 192.168.80.1:0 192.168.80.120:8080 192.168.80.136:8080
TCP 00:16 FIN_WAIT 192.168.80.1:49167 192.168.80.120:8080 192.168.80.136:8080
TCP 00:16 FIN_WAIT 192.168.80.1:49170 192.168.80.120:8080 192.168.80.136:8080
为什么要这么做?是因为:
官方解释:http://www.linuxvirtualserver.org/docs/persistence.html
我翻译了一部分。
有些Web服务可能用到HTTP Cookie,它是将数据存储在客户的浏览器来追踪和标识客户的机制。使用HTTP Cookie后,来同一客户的不同连接存在相关性,这些连接必须被发送到同一Web服务器。一些Web服务使用安全的HTTPS协议,它是HTTP协议加 SSL(Secure Socket Layer)协议。另有些Web服务可能使用安全的HTTPS协议,它是HTTP协议加SSL协议。当客户访问HTTPS服务(HTTPS的缺省端口为 443)时,会先建立一个SSL连接,来交换对称公钥加密的证书并协商一个SSL Key,来加密以后的会
话。在SSL Key的生命周期内,后续的所有HTTPS连接都使用这个SSL Key,所以同一客户的不同HTTPS连接也存在相关性。针对这些需要,IPVS调度器提供了持久服务的功能,它可以使得在设定的时间内,来自同一IP地 址的不同连接会被发送到集群中同一个服务器结点,可以很好地解决客户连接的相关性问题。
DR模式2个问题
1.rs的vip为何配在lo口?
2.dr模式中抑制了谁的arp响应?
内核针对arp的限制参数
echo"1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo"2" >/proc/sys/net/ipv4/conf/lo/arp_announce
echo"1" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo"2" >/proc/sys/net/ipv4/conf/all/arp_announce
arp_ignore:定义对目标地址为本地IP的ARP询问不同的应答模式0
我做了个arping的响应实验:arpping链路层检测
arping -I eth0 192.168.14.13 #通
arping -I eth0 192.168.14.100 #不通
说明 dr模式抑制了VIP的arp应答.
dr模式2个问题: 1,rs的vip为何配在lo口? 答: 防ip冲突 2,dr模式中抑制了谁的arp响应? 答: vip
怎么实现的呢? 通过arp的参数
0 - (默认值): 回应任何网络接口上对任何本地IP地址的arp查询请求
1 - 只回答目标IP地址是来访网络接口本地地址的ARP查询请求
2 - 只回答目标IP地址是来访网络接口本地地址的ARP查询请求,且来访IP必须在该网络接口的子网段内
3 - 不回应该网络界面的arp请求,而只对设置的唯一和连接地址做出回应
4-7 - 保留未使用
8 -不回应所有(本地地址)的arp查询
arp响应限制
1)arp_ignore:
定义对目标地址为本地IP的ARP询问不同的应答模式0
0 - (默认值): 回应任何网络接口上对任何本地IP地址的arp查询请求
1 - 只回答目标IP地址是来访网络接口本地地址的ARP查询请求
2 -只回答目标IP地址是来访网络接口本地地址的ARP查询请求,且来访IP必须在该网络接口的子网段内
3 - 不回应该网络界面的arp请求,而只对设置的唯一和连接地址做出回应
4-7 - 保留未使用
8 -不回应所有(本地地址)的arp查询
2)arp_announce:
对网络接口上,本地IP地址的发出的,ARP回应,作出相应级别的限制: 确定不同程度的限制,宣布对来自本地源IP地址发出Arp请求的接口
0 - (默认) 在任意网络接口(eth0,eth1,lo)上的任何本地地址
1 -尽量避免不在该网络接口子网段的本地地址做出arp回应. 当发起ARP请求的源IP地址是被设置应该经由路由达到此网络接口的时候很有用.此时会检查来访IP是否为所有接口上的子网段内ip之一.如果改来访IP不属于各个网络接口上的子网段内,那么将采用级别2的方式来进行处理.
2 - 对查询目标使用最适当的本地地址.在此模式下将忽略这个IP数据包的源地址并尝试选择与能与该地址通信的本地地址.首要是选择所有的网络接口的子网中外出访问子网中包含该目标IP地址的本地地址. 如果没有合适的地址被发现,将选择当前的发送网络接口或其他的有可能接受到该ARP回应的网络接口来进行发送.
[svc]高并发场景 LVS DR +KeepAlive高可用实现及ka的persistence_timeout参数的更多相关文章
- 高并发场景 LVS 安装及高可用实现
1.1 负载均衡介绍 1.1.1 负载均衡的妙用 负载均衡(Load Balance)集群提供了一种廉价.有效.透明的方法,来扩展网络设备和服务器的负载.带宽.增加吞吐量.加强网络数据处理能力.提高网 ...
- HttpClient在高并发场景下的优化实战
在项目中使用HttpClient可能是很普遍,尤其在当下微服务大火形势下,如果服务之间是http调用就少不了跟http客户端找交道.由于项目用户规模不同以及应用场景不同,很多时候可能不需要特别处理也. ...
- 高并发场景之RabbitMQ篇
上次我们介绍了在单机.集群下高并发场景可以选择的一些方案,传送门:高并发场景之一般解决方案 但是也发现了一些问题,比如集群下使用ConcurrentQueue或加锁都不能解决问题,后来采用Redis队 ...
- Qunar机票技术部就有一个全年很关键的一个指标:搜索缓存命中率,当时已经做到了>99.7%。再往后,每提高0.1%,优化难度成指数级增长了。哪怕是千分之一,也直接影响用户体验,影响每天上万张机票的销售额。 在高并发场景下,提供了保证线程安全的对象、方法。比如经典的ConcurrentHashMap,它比起HashMap,有更小粒度的锁,并发读写性能更好。线程安全的StringBuilder取代S
Qunar机票技术部就有一个全年很关键的一个指标:搜索缓存命中率,当时已经做到了>99.7%.再往后,每提高0.1%,优化难度成指数级增长了.哪怕是千分之一,也直接影响用户体验,影响每天上万张机 ...
- 【转】记录PHP、MySQL在高并发场景下产生的一次事故
看了一篇网友日志,感觉工作中值得借鉴,原文如下: 事故描述 在一次项目中,上线了一新功能之后,陆陆续续的有客服向我们反应,有用户的个别道具数量高达42亿,但是当时一直没有到证据表示这是,确实存在,并且 ...
- 高并发场景系列(一) 利用redis实现分布式事务锁,解决高并发环境下减库存
原文:http://blog.csdn.net/heyewu4107/article/details/71009712 高并发场景系列(一) 利用redis实现分布式事务锁,解决高并发环境下减库存 问 ...
- 高并发场景下System.currentTimeMillis()的性能问题的优化 以及SnowFlakeIdWorker高性能ID生成器
package xxx; import java.sql.Timestamp; import java.util.concurrent.*; import java.util.concurrent.a ...
- 高并发场景之RabbitMQ
高并发场景之RabbitMQ 上次我们介绍了在单机.集群下高并发场景可以选择的一些方案,传送门:高并发场景之一般解决方案 但是也发现了一些问题,比如集群下使用ConcurrentQueue或加锁都不能 ...
- 高并发场景下System.currentTimeMillis()的性能问题的优化
高并发场景下System.currentTimeMillis()的性能问题的优化 package cn.ucaner.alpaca.common.util.key; import java.sql.T ...
随机推荐
- java sm4国密算法加密、解密
java sm4国密算法加密.解密 CreationTime--2018年7月5日09点20分 Author:Marydon 1.准备工作 所需jar包: bcprov-jdk15on-1.59. ...
- 〖Linux〗简单的将Shell和一些文件打包成一个单独的“可执行文件”
有时候给别人分享一个工具的时候,同时需要提供的文件比较多: 如果分享一个压缩包还得教会对方如何解压.执行哪个脚本,感觉需要传输的内容多了就不方便: 把几个Shell脚本和文件打包成一个“单独的可执行文 ...
- python之模块pydoc
# -*- coding: cp936 -*- #python 27 #xiaodeng import pydoc #主要用于从python模块中自动生成文档,这些文档可以基于文本呈现,也可以生成we ...
- Ubuntu18.04下编译安装Guitarix 0.37.3
准备工作 源文件下载 https://sourceforge.net/projects/guitarix/files/guitarix/ 安装依赖. 参考 https://sourceforge.ne ...
- Uva10161 Ant on a Chessboard
Uva10161 Ant on a Chessboard 10161 Ant on a Chessboard One day, an ant called Alice came to an M*M c ...
- JavaScript原生对象及扩展
来源于 https://segmentfault.com/a/1190000002634958 内置对象与原生对象 内置(Build-in)对象与原生(Naitve)对象的区别在于:前者总是在引擎初始 ...
- CSRF攻击与防御(写得非常好)
转自:http://blog.csdn.net/stpeace/article/details/53512283 CSRF概念:CSRF跨站点请求伪造(Cross—Site Request Forge ...
- Python字典按值排序的方法
Python字典按值排序的方法: 法1: (默认升序排序,加 reverse = True 指定为降序排序) # sorted的结果是一个list dic1SortList = sorted( di ...
- java struts2入门学习--防止表单重复提交.OGNL语言学习
一.知识点回顾 防止表单重复提交核心思想: 客户端和服务器端和写一个token,比较两个token的值相同,则非重复提交;不同,则是重复提交. 1.getSession三种方式比较: request. ...
- java hibernate session create
public class RegisterStory { private SysUserCDao sysUserCDao; @Test public void test() { SessionFact ...