只解决c10k问题是不够的,单台主机的处理能力是有限的,一台主机同时处理500个动态网页请求已是极限了。这里有两种方法提高处理性能,一,定制高性能的计算机,众所周知计算机硬件设计成本极其高,性能每提升10%成本就要增长一倍,这也是intel被称为挤牙膏公司的缘由,不是其研发能力不行而是计算机硬件性能提高的难度太大,这个方法貌似不可行。二,使用两台主机处理业务,这就会引来一个问题怎么把请求分发到两个主机,这里咱们引入了负载均衡器。html
# 目录mysql
负载均衡nginx
lvs工做方式和调度方法算法
ipvsadm的使用sql
lvs-nat后端
lvs-dr缓存
多端口绑定和持久链接bash
# 负载均衡服务器
使用负载均衡有两个方法,一是采用商用负载均衡硬件的,这个方法是最好的方法,能上硬件必定不要使用软件,又是硬件一样的问题也是价格,只要是涉及到基础设施的服务必定要使用。一方面是硬件的稳定性,比软件好不少,虽然软件可维护性和拓展性比较好,可是对于一些金融公司,他们玩的就是公信力和大众信心,每一个故障都是竞争对手拆台的理由,一旦故障硬件背锅,理赔。经常使用的硬件F5的Big-IP,Citrix的Netscaler,A10的A10网络
另外一种是采用软件负载均衡,只要考虑成本使用负载均衡软件就对了,它的性能比硬件也不会差异太大,而且灵活。经常使用的有lvs,nginx,haproxy,ats。。。
在作负载均衡的时候,咱们在7层模型的哪一层作负载均衡,ip层基于主机作负载均衡粒度太大可用性太差基本不使用,更低的层基本上没有价值了,tcp层的话咱们就能够把不一样服务的请求采起不一样的方式负载均衡,应用层的话咱们能够根据具体协议拆包分析后负载均衡,既然涉及到拆开数据包,那处理的数据量就会大大增长,那么对计算机性能要求也越高,性能就越差,而且负载均衡器的通用性也越差。
传输层:lvs,nginx:(stream),haproxy:(mode tcp)
应用层:
http:nginx, httpd, haproxy(mode http)
fastcgi:nginx, httpd
mysql:mysql-proxy
# lvs工做方式和调度方法
### lvs的工做方式
有四种lvs-nat,lvs-dr,lvs-tun,lvs-fullnat
lvs集群类型中的术语:
vs:Virtual Server, Director, Dispatcher, Balancer
rs:Real Server, upstream server, backend server
CIP:Client IP, VIP: Virtual serve IP, RIP: Real server IP, DIP: Director IP
* lvs-nat
它的工做机制相似iptables的dnat功能,可是它工做于input链上。一次请求过程以下图
当客户端向director发送数据,数据在input链上目的地址vip换为rip后,被转发到postrouting链上过滤后发送到real server,real server处理完后把数据发送到director,director把这个数据的源地址rip更改成vip,固然lvs-nat不只仅是更改ip也能够更改端口,因此支持端口映射,由以上能够总结nat的特色,rip和dip必须在同一网络中,rs的网关须要指向dip,由于因此的数据必须通过director更改ip。
这种工做方式director很容成为网络瓶颈,由于因此的数据都要通过director,director网卡的吞吐量就表明整个网站的流量吞吐量,当今世界的慢慢走向5G,director是彻底不能知足需求的,须要借助其它网络设备帮助director分担流量,这就引入了lvs-dr模型。
* lvs-dr
如图,lvs-dr也是在input链上更改数据,可是它更改的不是ip地址而是mac地址,它把目的mac地址vmac更改成rmac,这里就要求vip,rip,dip必须在广播域内,可是地址不必定要在一个网段,由于他们间的通讯须要使用mac直接通讯。realserver处理请求后直接把数据返回给客户端。
等等,不对啊!realserver是怎么给客户端发送数据包的,realserver服务器上只有rip怎么用vip给客户端通讯,这里须要咱们给realserver配置vip。可是有一个问题,在网络中多个主机拥有同一个ip会产生冲突的,咱们的解决方案是只让一个主机发送arp广播而且响应arp请求,选谁毋庸置疑只能选择director。
控制arp广播arp-ignore,0广播,1不广播;控制响应arp-announce,0响应全部接口信息,1尽可能只响应当前网卡的信息,2只响应当前网卡的信息
lvs-dr的使用方法有两种,一种是每一个realserver都有与公网交互的公网ip,另外一种是只有内网ip,以后演示。
* lvs-tun
它是在本来的报文外部继续封装一个ip头,有可能形成超级帧
* lvs-fullnat
它是把源ip和目的ip都更改,至关于director请求realserver,realserver响应回来数据再把两个ip地址更改,这样这个数据包就能够跨越路由通讯了,nat原本就会形成director网络瓶颈,它的使用场景主要应用于请求数据量不大但后服务器数量不少的场景。
### 调度方法
调用方法能够分为两类,一类是静态调度算法,一类是动态调用算法
* 静态算法
rr #以轮询的方法,把请求转发到后端的主机
wrr #加权轮询,把请求按照必定的比例转发后端主机
sh #源地址哈希,把源地址作hash运算后,把realserver也hash,每一个realserver只处理本身hash和上一realserver的hash之间的源地址的请求如图
dh #目标地址哈希,这样realserver能够开启缓存了
* 动态算法
lc #最少链接,根据realserver的正在处理请求的数量进行调度,Overhead=activeconns*256+inactiveconns
wlc #加权最少链接,Overhead=(activeconns*256+inactiveconns)/weight
nq #在lc的基础上改进的,意思是不准有realserver主机空闲
sed #最短等等时间,Overhead=(activeconns+1)*256/weight
lblc #动态的DH算法;基于地址的最小链接数调度(locality-based least-connection):未来自同一个目的地址的请求分配给同一台RS,此时这台服务器是还没有满负荷的。不然就将这个请求分配给链接数最小的RS,并以它做为下一次分配的首先考虑
lblcr #带复制功能的lblc
# ipvsadm的使用
管理集群服务:增、改、删;
增、改:
ipvsadm -A|E -t|u|f service-address [-s scheduler] [-p [timeout]]
删:
ipvsadm -D -t|u|f service-address
[-s scheduler]:指定集群的调度算法,默认为wlc
service-address:
-t|u|f:
-t: TCP协议的端口,VIP:TCP_PORT
-u: TCP协议的端口,VIP:UDP_PORT
-f:firewall MARK,是一个数字;
管理集群上的RS:增、改、删;
增、改:
ipvsadm -a|e -t|u|f service-address -r server-address [-g|i|m] [-w weight]
删:
ipvsadm -d -t|u|f service-address -r server-address
server-address:
rip[:port]
# lvs-nat
nat实验拓扑图
这个使用我采用的是虚拟机,主机ip作cip,director的vip采用的桥接网络,dip和rip采用的是仅主机模式
realserver1执行的命令
yum install httpd -y #安装httpd echo rs1 > /var/www/html/index.html #提供网页文件
realserver2执行的命令
yum install httpd -y echo rs2 > /var/www/html/index.html
director执行的命令
yum install ipvsadm -y ipvsadm -A -t 172.16.29.4:80 -s wrr ipvsadm -a -t 172.16.29.4:80 -r 192.168.95.2 -m -w 1 ipvsadm -a -t 172.16.29.4:80 -r 192.168.95.3 -m -w 2
# lvs-dr
### 都采用公网ip的方案
全部网卡都采用桥接
director执行的命令
ifconfig eno16777736:0 172.16.29.4 netmask 255.255.255.255 broadcast 172.16.29.4 up #若在directer和realserver在同一个网段里必定要使用这一行 ipvsadm -A -t 172.16.29.4:80 -s wrr ipvsadm -a -t 172.16.29.4:80 -r 172.16.29.10 -g -w 1 ipvsadm -a -t 172.16.29.4:80 -r 172.16.29.20 -g -w 2
realserver执行的命令
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce ifconfig lo:0 172.16.29.4 netmask 255.255.255.255 broadcast 172.16.29.4 up route add -host 172.16.29.4 dev lo:0
### 只要一个公网ip的解决方案
所有接口采用的仅主机模式,而且每一个主机只有一个网卡,每一个网卡都先配置一个ip,后期再添加须要的ip
director要执行的命令
ifconfig eno16777736:0 192.168.95.20 netmask 255.255.255.0 broadcast 192.168.95.20 ipvsadm -A -t 192.168.95.20:80 -s wrr ipvsadm -a -t 192.168.95.20:80 -r 10.0.0.10 -g -w 2 ipvsadm -a -t 192.168.95.20:80 -r 10.0.0.20 -g -w 2
realserver须要执行的命令
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce ifconfig lo:0 192.168.95.20 netmask 255.255.255.255 broadcast 192.168.95.20 up route add -host 192.168.95.20 dev lo:0 route add default gw 10.0.0.1
路由设备须要执行的命令
echo 1 > /pro/sys/net/ipv4/ip_forward #开启转发功能
# 多端口绑定和持久链接
### FWM:FireWall Mark
借助于防火墙标记来分类报文,然后基于标记定义集群服务;可将多个不一样的应用使用同一个集群服务进行调度;
打标记方法(在Director主机):
# iptables -t mangle -A PREROUTING -d $vip -p $proto --dport $port -j MARK --set-mark NUMBER
基于标记定义集群服务:
# ipvsadm -A -f NUMBER [options]
### lvs persistence:持久链接
持久链接模板:实现不管使用任何算法,在一段时间内,实现未来自同一个地址的请求始终发往同一个RS;
ipvsadm -A|E -t|u|f service-address [-s scheduler] [-p [timeout]]
port Affinity:
每端口持久:每集群服务单独定义,并定义其持久性;
每防火墙标记持久:基于防火墙标记定义持久的集群服务;可实现将多个端口上的应用统一调度,即所谓的port Affinity;
每客户端持久:基于0端口定义集群服务,即将客户端对全部应用的请求通通调度至后端主机,并且可以使用持久链接进行绑定;
# 总结
lvs是负载均衡器中最基本的,理解了它的原理和使用方法,基本上掌握了大多数的负载均衡器的原理。其中dr模型是必须掌握的,真正使用的话我感受会使用dr,net的功能颇有可能被7层代理的服务器替代了。多端口绑定功能也很经常使用好比80和443端口绑定统一调度;持久链接虽然破坏调度效果,可是在没有session缓存服务器的话仍是很高效的。