一、集群相关概念
1、cluster-LB(load balancing)
http(stateless无状态协议,就算使用长连接也有时间限定)
每一页面有众多的web object
若一台server配置4Gmemory,2*cpu;若同时200个请求中有50个dynamic(200个网络IO、磁盘IO都由CPU处理,150*2M=50*10M=800M);若200à1000个请求(1000个请求中200个dynamic,800*2M=200*10M=3.6G,除网络IO磁盘IO还有CS进程间切换也相当耗资源,这时服务器有可能扛不住)
Scale on(向上扩展,使这台对外提供服务的server配置提升至16G,8*cpu,配置比之前提升4倍,但性能增长多少,价格又多了多少,CPU颗数越多彼此间产生的资源竞争也越大,越耗资源,解决此问题可能已超出上限,所以仅将这一台server配置提升,将在一定范围内适用,总有一个临界点,配置再提升性能将不提升或提升很小,但这产生的价钱是中小企业难以承受的,而且可扩展性也受到限制,因为之前的所有资源都要迁移至新的一台server)
Scale out(向外扩展,增加或减少服务器的数量,可方便地增加或减少总的处理能力,将请求根据某种调度算法,分配到后端的所有server上(类似dns,将一个域名解析到不同的server上),这种能力叫负载均衡LB(load balancing)),LB服务很复杂,如工作在passive模式下FTP的LB,mysql的LB
一个用户请求的一个页面,可能来自多个主机,组成的这多个主机完成同一种任务的结构叫负载均衡集群
若一论坛,某一用户在集群的某一主机上发了一个帖子,下次访问被前端的调度器director分到后端的real server(RS)与之前不在同一主机上,之前发的帖子是否仍能访问到;该论坛还允许用户上传附件,附件的保存位置?如图片是不能在数据库中存放的;网页的页面文件位置?
在后端单独拿出一台server做成NFS共享,用于存储附件,而数据库中保存的是附件的链接;页面文件不应放在NFS共享存储上(文件级别传输,性能不高,并发处理能力有限),页面文件应放在后端每一台RS的本地,页面文件若有变化,使用rsync+inotify(若是大文件可在客户端装sersync用以到server同步)
rsync(文件同步工具,在复制前先检查源和目的目录中的文件,相同的会跳过,将不同的复制同步,高效的复制工具,且支持远程复制)
inotify(类似dns,slave每隔多长时间到master请求同步数据(refresh定义的时间),若slave刚同步过master就发生了改变,可在slave上安排计划任务(每5分钟同步一次),一般做法是master发生改变就向其它slave通知,文件内容发生改变是内核管理的,内核将这种监控文件本身是否发生改变的功能输出给用户空间,用户空间才有可能知道,通过inotify就可实现此功能)
sersync(金山公司,C++开发,性能高,支持并发多线程复制,适合大文件传输,且服务器多的场景,接受inotify通知,运行在client)
若访问量1000-->5000-->8000,通过增加server,性能到达某一临界点也无法提升(如,前端的director承受不了),这时就要根据网站的不同版块,将服务器集群划分区域(如sina的主页上有新闻、军事、社会,主页是个整合的页面,通过点击不同的版块,将会自动转至不同的服务器集群)
2、cluster-HA(high availability)
以上director易成为单点故障,可增加一台备份,这样primary、secondary(或active、standby),将有两台director,当前工作的primary通过网络连接每隔1秒向外通知它依然在线,如果secondary在1秒内未收到,再1秒又未收到,连续三次将取而代之
LB也能实现HA,但依赖于前端director,这虽然具有一定的高可用能力,但不是高可用集群(后端的某一RS挂了,director仍根据事先定义的算法将请求转发至该RS,这时用户将得到服务无法访问,这不是我们希望看到的,所以只要director不将请求转至有问题的real-server即可,这就是通过前端的director实现后端RS的健康状况检查health check,不但检查好-->坏,还检查坏-->好)
LB与HA的区别(HA集群中每个节点node会向其它node通知它自身的心跳信息)
LB:提高服务的并发处理能力为着眼点(并发处理能力)
HA:提供服务的始终在线能力为着眼点(服务的可用性)
HA中:无故障时间=在线时间/(在线时间+故障处理时间)*100%(通常以有多少个9衡量)
如99%(一年中3天故障)
99.9%(0.3天)
99.99%(0.03天)
99.999%(0.003,约3到5分钟)
为提高资源利用率可将前端的两个director各运行一个服务(web,mail),其中若primary故障可将服务切至secondary(那secondary要运行两个服务,primary亦然)
在HA集群里,一般一个资源在同一时刻只能被一个node所占用(一个server就是一个node),两个服务在一个node上工作,使用的是不同的资源
若有三个服务,就有倾向性(优先级),如web(RS1),smtp(RS2),pop3(RS3)
通过网络不停地发送自己的心跳(组播或多播,只向特定主机传送,在同一组播域内的主机)
在HA集群中,各node间不仅传送心跳信息,还有其它集群事务信息(DC推选的事务协调员,负责监督,各node间如何通过倾向性转移服务,协调各node间完成事务的node,这个node称为DC,若DC挂了,再重新推选一个DC)
RAID阵列(块级别交换数据,性能好,内核通过驱动直接操作数据,DAS(direct attachment storage)直接附加存储)
NFS(文件级别交换数据,一个文件可能包含N个data block,对于前端主机看来是文件共享服务器,NAS(network attachment storage)网络附加存储)
若一个主机的两个进程写同一文件(通过加锁,另一进程将访问不了)
若两个主机写同一文件(两个进程分别在不同的主机,其中一个主机加锁,另一主机并不知道)
每一个文件要被主机访问,无论读还是写,都会放到内存缓冲区中,读写操作一定是在内存中完成的,过段时间才同步到磁盘中去,每一个文件第一次被一主机写时,它的源数据和数据已被加载到这一主机的内存中,第二个主机也加载到它的内存中,各自的写都在自己的内存中完成,最后都要同步到磁盘,同步一合并,第一个主机新增两行,第二个主机删除了10行,理想的情况是第一个主机修改好了第二个主机再改,如果两者交叉使用,FS文件系统会错乱
NFS(或NAS):两个主机同时写一个文件不会导致FS错乱,当有一主机写一文件时,NFS-server会自动给其施加锁(NFS-server代为持有锁),第二个主机向同一文件发起写操作时,NFS-server会拒绝其写
DAS在高可用集群中,若secondary未收到primary的心跳信息就取而代之(夺回IP,相应进程启动,往磁盘上写数据),实际上primary并没挂还在正常工作,只是太忙了没工夫传自己的心跳,但secondary误认为primary已死,它也往磁盘上写数据了并且操作了同一文件,结果FS错乱了,产生split-brain(脑裂,左右不协调了)
为避免split-brain,secondary在抢占资源前,想方设法将primary挂透,如直接拔掉其电源(通过电源交换机设备),这种功能叫STONITH(shoot the other node in the heart暴头)
避免某一node访问资源的机制叫fencing(隔离)
资源隔离级别两种:节点级别(STONITH);资源级别(前提要求硬件具有设备管理能力,允许能接受远程管理指令才行)
为避免集群分裂,node的数量至少要有3个(奇数个node,超过半数),且要有仲裁机制,如当某一node挂掉时判定集群中的node哪一半是有效的,哪一半是无效的
注:集群服务中,各节点间的时间偏差不应超过1s,尤其是HA高可用集群
3、cluster-HP(highperformance或HPC high performance computer)
向量机(仅一台超强的机器,受磁盘IO影响处理能力有限)
化整为0(找一堆计算机,每个node只处理一部分数据,每个node既处理又存储(分布式存储,分布式FS),之后要处理数据时,直接在每个node的存储位置处启动一个进程来处理本地存储的数据)
并行处理集群(分布式FS,将大任务切割成小任务,分别进行处理的机制,如hadoop)
二、LVS
LB(LVS)
1、 相关概念
harware:F5的bigip、citrix的netscaler、A10的AX系列
software:四层实现的LVS(linuxvirtual server,只解析四层,性能好,对应用层协议中的内容不作任何处理,不解析高层协议,支持的高级特性没有,如根据用户请求的资源URL做LB);七层实现的nginx,haproxy(http,smtp,pop3,imap,也可用于四层如mysql(tcp),精确解析七层协议,且在协议上作一定修改后再LB,操作能力强,性能略逊于LVS,在一些场景下,七层为某些特定场景所提供,更符合生产环境需要)
根据用户请求的IP地址和PORT来判定是不是要转发至后端的服务(需要将其定义为集群服务,才向后转发)
若未定义ssh服务22port,则不转发,就是director自己
LVS本身工作在内核上的TCP/IP协议栈(借鉴了netfilter的框架);LVS与iptables不能同时使用;client请求到达director经PREROUTING链到INPUT链,ipvs若发现请求的是已定义的集群服务则直接经POSTROUTING转出,若请求的非集群服务从而到达本地的用户空间
LVS也是两段式:ipvsadm是工具(在用户空间管理集群服务的命令行工具);内核中的ipvs监控在内核的框架
2.4.23和2.6.2以后的内核直接内置了ipvs代码,支持ipvs功能,只要在用户空间再安装ipvsadm就可实现LB的调度器
一个 director可为多个服务提供调度功能,但通常只为一个服务提供调度(正因为一个server并发能力弱才需多台server)
CIP(client IP)
VIP(virtual IP)
DIP(director IP)
RIP(real server IP)
type of LVS cluster:
LVS-NAT(地址转换,工作机制同DNAT,只不过是多目标)
LVS-DR(direct router直接路由)
LVS-TUN(tunneling隧道)
basic properties of LVS-NAT:
后端各RS(集群各节点)要与director在同一网段,且RS的网关要指向director;
RIP通常是私有地址,仅用于各node间通信;
director位于client和RS之间,负责进出的所有通信;
支持端口映射;
RS可使用任意OS;
较大规模应用场景中,director易成为系统瓶颈bottleneck
basic properties of LVS-DR:
集群各节点与director必须在同一个物理网络中(同一机房,甚至同一机柜中);
RIP可以是私有地址,也可以是公网地址(实现便捷的远程管理和维护);
director仅负责入站请求,响应报文由各RS直接发往client;
集群各节点一定不能将网关设为DIP;
director不支持端口映射;
大多数OS都可以是RS(要能实现隐藏VIP功能);
DR模型比NAT模型支持更多的RS
注:使用DR模型,结合LVS(LVS性能非常强劲,已突破了socket(文件数目)的限制),若对server的内存和CPU优化得当,配置4G-8G内存,2-4颗CPU并发几万至几十万连接是没问题的)
所有主机均一块网卡
如图:
请求:client(源地址CIP,目标地址VIP)-->router-->switch-->director根据算法-->任一RS
响应:RS直接响应-->client(源地址VIP,目标地址CIP)
每个主机接入网络或开机时,都会通告自己的IP地址和MAC地址,以方便与其它主机通信,其它主机将在本地缓存解析到的所有主机的IP与MAC的对应关系,缓存有过期时间默认300秒
director、RS{1,2,3}在同一switch下,通过ARP解析广播得到各自的MAC地址,进而彼此间可以互相通信,报文基于MAC转发,在同一网段内的主机,这些主机的接口都配置了目标VIP的地址,client的请求报文到达switch后,这些主机都有可能接收到,如果都响应,那router就混乱了,哪个主机响应快就将报文转到该主机的接口,这里要保证LB的效果,所以务必保证仅只有director可以接收此报文,各RS都不能接收,这就要求各RS不能对ARP解析请求给予响应,也就是要屏蔽RS的VIP,如何屏蔽?
三种方式:在router接口上绑定配置(director的MAC与VIP地址绑定,静态且不会失效,这种方式固然简便有效,但不可行,VIP是公网地址,大多数情况下这个router是运营商的,并不在本地);arptables(类似iptables,基于MAC地址作访问控制,redhat系列支持fedora,centos);内核参数kernel parameter(ip_ignore(限定linux主机对arp广播请求的响应级别),arp_announce(向外通告的通告级别))
director转发报文至各RS上时,不改变目标地址,仅修改MAC地址(当用户请求到达director后,director发现是个集群服务,根据调度算法假设选定了RS2,它不会拆IP首部(标示源IP目标IP)和TCP首部(标示源端口目标端口),只是拆掉MAC首部再重新封装(帧,修改后的源MAC是directorMAC,目标MAC是RS2MAC),RS2收到报文后发现目标是它自己的,拆掉帧封装的MAC后,看到源IP(CIP)目标IP(VIP),发现自己主机上有VIP,就认为到它自己本机了,响应时源IP(VIP)目标IP(CIP)),如何做到让响应报文的源IP一定是VIP?(因为client请求的是VIP,不是RIP)
解决方法:添加一条路由信息即可#route add -host SRC_IP dev lo:0(默认linux的路由策略:响应报文的源地址是流出接口配置的地址(也就是eth0上配置的RIP),若流出接口与默认网关不在同一网段,则使用此接口配置的别名地址)
响应报文的源IP目标IP已就绪,怎么出去?(client的请求经router是到director,也就是router和director在同一网段,RS的响应报文若也要从 router的这个口出去,要在这个口上配置别名地址,这个别名地址是后端RS的默认网关,也可从router的其它口出,也可以单独拿出一台路由器从这台路由器上出去;以下的实验是将director和各RS放在同一网段,一般生产环境不是这样的)
一般请求的报文小,响应的报文大,这样不经director性能提高N倍
注:arp_ignore(arp广播请求的响应级别,配置对什么级别的网卡给予响应;0默认,只要本地配置的有相应地址就给予响应;1仅在请求的目标地址配置在请求到达的接口上时才给予响应)
arp_announce(主动向外通告级别,将自己的地址向外通告时的通告级别;0默认,将本地任何接口上的任何地址向外通告;1,try to avoid试图仅向目标网络通告与其接口匹配的地址;2,always use the best local address for this target仅将与本地接口上的地址向匹配的网络进行通告
使用:arp_ignore=1,arp_announce=2
basic properties of LVS-TUN(主机OS要支持隧道机制):
与DR工作机制一样,只不过在转发时要重新封装报文(在源地址CIP目标地址VIP的基础上,再封装一次报文,加上源地址DIP目标地址RS2IP,借助于一个IP报文再发送一个IP报文——隧道),适用于RS在异地(不在同一网络内);
集群各节点可以跨越internet;
RIP必须是公网地址;
director仅处理入站请求,响应报文由各RS直接发往client;
RS不能将网关指向director;
只有支持隧道功能的OS才能用于RS;
不支持端口映射
scheduling method:
静态调度(固定调度,不考虑当前server是空闲还是繁忙(当前建立的活动连接active(用户请求进来,正在实现数据传输)和非活动连接inactive(连接建立,数据传输结束,但尚未断开)):rr,wrr,sh,dh
rr,round robin,轮叫,轮询;
wrr,weight rr,加权轮询,以权重之间的比例进行;
sh,source hashing,源地址哈希,会话绑定sessionaffinity(能让用户此前建立的信息继续使用);只要是来自同一client的请求,都转发至同一个RS(在director本地保存了一张hash表),这在一定程度上破坏了LB的效果,但在具体应用中又是必须的(如电商网站的购物车)
;session会话结合cookie进行;如果配置了session-sharing会话共享(memcached,解决RS挂掉session丢失)就可以不使用sh
注:http(stateless,每一次用户的请求都被视作一个新的请求,它无法识别client来源与此前发起的请求来源之间有什么关系,更不用说认证);
注:cookie(让server追踪client的机制,在client第一次访问时,server会生成一段标示给client,还会记录此前client访问的URL链接及身份认证等信息,client会把这些信息保存在本地的cookie文件中,client再次访问server时会自动将cookie附加在请求中,后续的每一个client请求server都能接收到,进而两次访问的都一样,server根据cookie就知道这是同一个client;早期的cookie是无法区分网站的,当client访问每一个网站时在cookie中选一批发送到server,这是相当危险的,server就知道client访问过哪些网站(从而有目的的搜集个人隐私及投放针对性的广告),所以cookie有可能被滥用,避免这种情况,现在都实现了轻cookie,在client仅保存标示信息到cookie文件,而不再保存用户浏览的信息,这些浏览的信息保存在了server上,server在它的内存中为每一个cookie(身份标识)关联一个内存区域(保存用户的浏览信息),这个内存区域保存相关信息的机制就是session,session借助cookie识别用户身份),session有过期时间(会被清理);另一机制(基于URL重写也可以server追踪client,比较复杂)
注:session-sharing,可通过memcached(常用)实现,也可将后端的RS做成集群,每一个主机都保存有该网张内的所有session
dh,destination hashing,将同一个IP的请求发送给同一RS,以目标地址为着眼点进行挑选(功能近似sh,适用于cache-server,第一个client请求内容,RS响应时先给cache-server保留一份再响应给client,当第二个client请求同样内容时,为使缓存命中,director必须要将请求转至cache-server,cache-server中若有直接响应,若无再找RS)
动态调度:lc,wlc,sed,nq,lblc,lblcr
lc,least connection,最少连接,计算当前backend后端RS的active和inactive的总数,作比较后,哪一个连接少就选哪个,计算方法:active*256+inactive谁的小挑谁
wlc,weight lc,加权最少连接,默认最理想的调度算法(考虑到inactive,inactive虽然占用资源少,但在数量很大时是不能忽略的),计算方法:(active*256+inactive)/weight谁的小挑谁
sed,shortest expected delay,最短期望延迟,它不考虑inactive,权重大的优先被选中,权重小的一直空闲,计算方法:(active+1)*256/weight
nq,never queue,永不排队,刚开始先保证每个RS都在处理,之后的请求再根据权重分配
lblc,locality based least connection,基于本地的最少连接,与dh一样用于缓存服务器的场景中,lblc考虑cache-server的连接数,保证每个cache-server都在忙,尽可能找一空闲的server响应,坏处(有可能破坏命中率),而dh不考虑cache-server的连接数
lblcr,lblc replication,带复制功能的基于本地的最少连接,既保证LB效果又保证命中率,两个RS间通过内容分发协议实现缓存共享(缓存复制机制,兄弟服务器)
2、 操作:
#grep -i “ip_vs” /boot/config-2.6.18-308.el5
CONFIG_IP_VS=m
# CONFIG_IP_VS_DEBUG is not set
CONFIG_IP_VS_TAB_BITS=12
CONFIG_IP_VS_PROTO_TCP=y
CONFIG_IP_VS_PROTO_UDP=y
CONFIG_IP_VS_PROTO_ESP=y
CONFIG_IP_VS_PROTO_AH=y
CONFIG_IP_VS_RR=m
CONFIG_IP_VS_WRR=m
CONFIG_IP_VS_LC=m
CONFIG_IP_VS_WLC=m
CONFIG_IP_VS_LBLC=m
CONFIG_IP_VS_LBLCR=m
CONFIG_IP_VS_DH=m
CONFIG_IP_VS_SH=m
CONFIG_IP_VS_SED=m
CONFIG_IP_VS_NQ=m
CONFIG_IP_VS_FTP=m
#cd /mnt/cdrom/Cluster
#rpm -ivh ipvsadm-1.24-13.el5.i386.rpm
#rpm -ql ipvsadm
/etc/rc.d/init.d/ipvsadm
/etc/sysconfig/ipvsadm-config
/sbin/ipvsadm
/sbin/ipvsadm-restore
/sbin/ipvsadm-save
管理集群服务:-A添加、-E修改、-D删除
#ipvsadm -A|-E -t|-u|-f SERVICE_ADDRESS -s SCHEDULER(-t,tcp;-u,udp;-f,FWM,firewallmark防火墙标记;SERVICE_ADDRESS表示为IP:PORT;-s指定算法,不指默认为wlc)
#ipvsadm -D -t|-u|-f SERVICE_ADDRESS
管理集群服务中的RS:-a添加、-e修改、-d删除
#ipvsadm -a|-e -t|-u|-f SERVICE_ADDRESS -r SERVER_ADDRESS -g|-i|-m -w WEIGHT(SERVICE_ADDRESS表示事先定义好的集群服务;SERVER_ADDRESS表示为RS的IP地址,在NAT模型中可使用IP:PORT实现端口映射;LVS类型,-g表示DR,-i表示TUN,-m表示NAT,不写默认DR模型;-w指定权重)
#ipvsadm -d -t|-u|-f SERVICE_ADDRESS -r SERVER_ADDRESS
#ipvsadm -L|-l -n(-L|-l,--list;-n,--numeric)
#ipvsadm -L -n --stats(统计信息Conns,InPkts,OutPkts,InBytes,OutBytes)
#ipvsadm -L -n -rate(速率,CPS(connectionper second),InPPS(package per second),OutPPS,InBPS,OutBPS)
#ipvsadm -L -n --timeout(session的超时时长)
#ipvsadm -L -n --sort
#ipvsadm -L -n -c(connection output,显示当前ipvs的连接状况,有多少client连进)
#ipvsadm -Z(清空计数器)
#ipvsadm --daemon(daemon status andmulticast interface)
#ipvsadm -C(清空所有ipvs规则,删除所有集群服务)
#ipvsadm -S > /path/to/somefile(保存规则,同ipvsadm-save)
#ipvsadm -R < /path/from/somefile(载入此前定义的规则,同ipvsadm-restore)
#service ipvsadm save(默认保存至/etc/sysconfig/ipvsadm)
1)LVS-NAT实例(redhat5.8 32bit 2.6.18-308.el5):
director-side:
#echo 1 > /proc/sys/net/ipv4/ip_forward
#ipvsadm -A -t 192.168.1.222:80 -s rr
#ipvsadm -a -t 192.168.1.222:80 -r 192.168.1.223:80 -m
#ipvsadm -a -t 192.168.1.222:80 -r 192.168.1.224:80 -m
#ipvsadm -L -n
#ipvsadm -S > /etc/sysconfig/ipvsadm.web.nat
RS{1,2}上配置好httpd服务及页面内容
在windows的物理机上浏览器测试
#ipvsadm -E -t 192.168.1.222:80 -s wrr
#ipvsadm -e -t 192.168.1.222:80 -r 192.168.1.223 -m -w 3
#ipvsadm -e -t 192.168.1.222:80 -r 192.168.1.224 -m -w 1
#ab -c 100 -n 1000 http://192.168.1.222/index.html
#ipvsadm -L -n --stats
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Conns InPkts OutPkts InBytes OutBytes
-> RemoteAddress:Port
TCP 192.168.101.169:80 1009 5045 5045 372603 553095
-> 192.168.1.224:80 252 1260 1260 93186 141008
-> 192.168.1.223:80 757 3785 3785 279417 412087
2)LVS-DR实例(redhat5.8 32bit 2.6.18-308.el5):
注:此实验将VIP与DIP、RIP放在同一网段,现实生产中并不是这样(一般VIP是公网地址,RIP与DIP是私有地址;为管理方便RIP也可以是公网地址;若不在同一网段,RS的响应报文要从router的其它口出去,而不是router进来的这个口,或者经另一router出去)
director-side:
#sed -i ‘s@net.ipv4.ip_forward = 0@net.ipv4.ip_forward = 1@g’ /etc/sysctl.conf
#ipvsadm -A -t 192.168.1.222:80 -s rr
#ipvsadm -a -t 192.168.1.222:80 -r 192.168.1.61 -g
#ipvsadm -a -t 192.168.1.222:80 -r 192.168.1.62 -g
#ipvsadm -L -n
#ipvsadm-save > /etc/sysconfig/ipvsadm.web.dr
#ifconfig eth0:0 192.168.1.222 broadcast 192.168.1.222 netmask 255.255.255.255(四个255表示这一个网段就这一个主机)
#route add -host 192.168.1.222 -dev eth0:0
RS{1,2}-side:
#sysctl -w net.ipv4.conf.all.arp_ignore=1
#sysctl -w net.ipv4.conf.all.arp_announce=2
#sysctl -w net.ipv4.conf.lo.arp_ignore=1
#sysctl -w net.ipv4.conf.lo.arp_announce=2
#sysctl -p
注:要先屏蔽通告及响应级别,再配置lo:0上的VIP地址,否则提示地址已用
注:/proc/sys/net/ipv4/conf/{all,eth0|lo},其中all必须要配置,eth0和lo选一个配置即可;
#ifconfig lo:0 192.168.1.222 broadcast 192.168.1.222 netmask 255.255.255.255
#route add -host 192.168.1.222 dev lo:0
附加:在director-side也可开启httpd服务,仅用于提供错误页面(若后端RS全都不能提供服务时使用director上提供的错误页面)
#ipvsadm -a -t 192.168.1.222:80 -r 127.0.0.1 -g
#ipvsadm -L -n
3、 LVS持久连接:
无论使用何种算法,都能实现在一定时间内,将来自同一个client的请求派发至此前选定的RS,对不同服务的请求也定向至同一个RS(它能将同一个client的所有请求都定向到同一个RS上)
在基于SSL会话时,最需要用到持久连接(彼此间发送密钥、证书等,若每次都要重新建立连接,相当耗费资源)
dh算法依赖于tcp协议的超时时间
持久连接模板(内存的一段缓冲区):记录每一个client与分配给它的RS的映射关系(对应关系)、及超时时长(时间到时从模板中删除,下次连接再重新调度)
#ipvsadm -L -n --persistent-conn(输出持久连接信息)
#ipvsadm -L -n -c(--connection,client与RS的对应关系,pro,expire,state,source,virtual,destination)
#ipvsadm -A|-E -t SERVICE_ADDRESS -s SCHEDULER -p TIMEOUT(添加或修改集群服务时指定持久连接时长,默认300秒,时间到时,若连接尚未断开,会自动延长时间2min,若2min之后还在连接再延长2min,直到超时断开连接)
持久连接提供两个功能:
PPC(persistent portconnection持久端口连接,将来自于同一个client对同一个集群服务的请求,始终定向至此前选定的RS,PPC仅保证对同一个服务持久)
PCC(persistent clientconnection持久客户端连接,将来自于同一个client对所有端口的请求,始终定向至此前选定的RS,PCC此种方式会将所有端口统统定义为集群服务一律向后端RS转发)
补充:PPC定义了仅一个服务持久,PCC定义了所有服务持久,能否自定义有限的几个服务持久?(借助于iptables防火墙标记实现,在mangle表的PREROUTING链,使用-j MARK --set-mark MARK_NUMBER,MARK_NUMBER是0-99的整数,选择此前尚未使用的即可)
举例:PPC
director-side:
#ipvsadm -E -t 192.168.1.222:80 -s rr -p 600
#ipvsadm -L -n
#ipvsadm -L -n --persistent-conn
RS{1,2}-side:
#chkconfig telnet on
#service xinetd restart
#useradd hadoop(telnet服务不允许远程root登录)
#passwd hadoop
在win上测试RS的telnet服务是否正常(非集群服务测试)
director-side:
#ipvsadm -C
#ipvsadm -A -t 192.168.1.222:23 -s rr -p 600
#ipvsadm -a -t 192.168.1.222:23 -r 192.168.1.61 -g
#ipvsadm -a -t 192.168.1.222:23 -r 192.168.1.62 -g
在win上测试(集群服务测试)
举例:PCC
#ipvsadm -C
#ipvsadm -A 192.168.1.222:0 -s rr -p 600(0表示所有端口的服务都是集群服务)
#ipvsadm -a 192.168.1.222:0 -r 192.168.1.61 -g
#ipvsadm -a 192.168.1.222:0 -r 192.168.1.62 -g
重新启动一台虚拟机测试:#ssh 192.168.1.222
在director-side查看:#ipvsadm -L -n -c(不同的服务state会不一样)
举例:借助防火墙标记,定义指定的服务持久(将对http与https的请求始终定向至同一台RS,80和443绑定在一起)
#ipvsadm -C
#iptables -t mangle -A PREROUTING -d 192.168.1.222 -i eth0 -p tcp --dport 80 -j MARK --set-mark 8
#iptables -t mangle -A PREROUTING -d 192.168.1.222 -i eth0 -p tcp --dport 443 -j MARK --set-mark 8
#ipvsadm -A -f 8 -s rr -p 600
#ipvsadm -a -f 8 -r 192.168.1.61 -g
#ipvsadm -a -f 8 -r 192.168.1.62 -g
注:memcached(高性能cache-server,用于session-shared),在电商站点,购物车中的商品,这些信息保存在server-side的session中,要么做持久连接,要么使用session-shared,付款环节https,80和443要绑定在一起,两个RS使用同一个证书
4、脚本实现:
命令#service ipvsadm save与#ipvsadm-save等不能保存路由配置
#curl --connect-timeout 1 http://IP(指定连接超时时间)
#curl -I http://IP(获取页面的响应首部)
#curl -s http://IP(静默模式,不输出任何内容)
#elinks -dump http://IP | grep “RS1”
#echo $?(若能grep到页面内容,就证明某RS在线,可用于判定RS是否在线)
#vim health_check.sh
#!/bin/bash
#在director-side实现后端RS健康状况检查
VIP=192.168.1.222
CPORT=80
FAIL_BACK=127.0.0.1
RS=("192.168.1.61""192.168.1.62")
declare -a RSSTATUS
RW=("2" "1")
RPORT=80
TYPE=g
CHKLOOP=3
LOG=/var/log/ipvsmonitor.log
addrs() {
ipvsadm -a -t $VIP:$CPORT -r $1:$RPORT -$TYPE -w $2
[$? -eq 0 ] && return 0 || return 1
}
delrs() {
ipvsadm -d -t $VIP:$CPORT -r $1:$RPORT
[$? -eq 0 ] && return 0 || return 1
}
checkrs() {
local I=1
while [ $I -le $CHKLOOP ]; do
if curl --connect-timeout 1 http://$1 &> /dev/null; then
return 0
fi
let I++
done
return 1
}
initstatus() {
local I
local COUNT=0;
forI in ${RS[*]}; do
if ipvsadm -L -n | grep "$I:$RPORT" && > /dev/null; then
RSSTATUS[$COUNT]=1
else
RSSTATUS[$COUNT]=0
fi
letCOUNT++
done
}
initstatus
while :; do
letCOUNT=0
forI in ${RS[*]}; do
if checkrs $I; then
if [ ${RSSTATUS[$COUNT]} -eq 0 ]; then
addrs $I ${RW[$COUNT]}
[ $? -eq 0 ] &&RSSTATUS[$COUNT]=1 && echo "`date +'%F %H:%M:%S'`, $I isback." >> $LOG
fi
else
if [ ${RSSTATUS[$COUNT]} -eq 1 ]; then
delrs $I
[ $? -eq 0 ] && RSSTATUS[$COUNT]=0 && echo "`date+'%F %H:%M:%S'`, $I is gone." >> $LOG
fi
fi
let COUNT++
done
sleep 5
done
#vim director.sh
#!/bin/bash
#用于director-side
# LVS script for VS/DR
# chkconfig: - 90 10
#
. /etc/rc.d/init.d/functions
#
VIP=192.168.1.222
DIP=192.168.1.60
RIP1=192.168.1.61
RIP2=192.168.1.62
PORT=80
RSWEIGHT1=1
RSWEIGHT2=3
#
case "$1" in
start)
/sbin/ifconfig eth0:0 $VIP broadcast $VIP netmask 255.255.255.255 up
/sbin/route add -host $VIP dev eth0:0
# Since this is the Director we must beable to forward packets
echo 1 > /proc/sys/net/ipv4/ip_forward
# Clear all iptables rules.
/sbin/iptables -F
# Reset iptables counters.
/sbin/iptables -Z
# Clear all ipvsadm rules/services.
/sbin/ipvsadm -C
# Add an IP virtual service for VIP192.168.1.222 port 80
# In this recipe, we will use theround-robin scheduling method.
# In production, however, you should use aweighted, dynamic scheduling method.
/sbin/ipvsadm -A -t $VIP:80 -s wlc
# Now direct packets for this VIP to
# the real server IP (RIP) inside thecluster
/sbin/ipvsadm -a -t $VIP:80 -r $RIP1 -g -w $RSWEIGHT1
/sbin/ipvsadm -a -t $VIP:80 -r $RIP2 -g -w $RSWEIGHT2
/bin/touch /var/lock/subsys/ipvsadm &> /dev/null
;;
stop)
# Stop forwarding packets
echo 0 > /proc/sys/net/ipv4/ip_forward
# Reset ipvsadm
/sbin/ipvsadm -C
# Bring down the VIP interface
/sbin/ifconfig eth0:0 down
/sbin/route del $VIP
/bin/rm -f /var/lock/subsys/ipvsadm
echo "ipvs is stopped..."
;;
status)
if[ ! -e /var/lock/subsys/ipvsadm ]; then
echo "ipvsadm is stopped ..."
else
echo "ipvs is running ..."
ipvsadm -L -n
fi
;;
*)
echo "Usage: $0 {start|stop|status}"
;;
esac
#vim rs.sh
#!/bin/bash
#用于RS-side
# Script to start LVS DR real server.
# chkconfig: - 90 10
# description: LVS DR real server
#
. /etc/rc.d/init.d/functions
VIP=192.168.1.222
host=`/bin/hostname`
case "$1" in
start)
# Start LVS-DR real server on this machine.
/sbin/ifconfig lo down
/sbin/ifconfig lo up
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
/sbin/ifconfig lo:0 $VIP broadcast $VIP netmask 255.255.255.255 up
/sbin/route add -host $VIP dev lo:0
;;
stop)
# Stop LVS-DR real server loopback device(s).
/sbin/ifconfig lo:0 down
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce
echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce
;;
status)
# Status of LVS-DR real server.
islothere=`/sbin/ifconfig lo:0 | grep $VIP`
isrothere=`netstat -rn | grep "lo:0" | grep $VIP`
if [ ! "$islothere" -o ! "isrothere" ];then
# Either the route or the lo:0 device
# not found.
echo "LVS-DR real server Stopped."
else
echo "LVS-DR real server Running."
fi
;;
*)
# Invalid entry.
echo "$0: Usage: $0 {start|status|stop}"
exit 1
;;
esac
本文转自 chaijowin 51CTO博客,原文链接:http://blog.51cto.com/jowin/1715354,如需转载请自行联系原作者