负载均衡集群比较主流的开源软件有:LVS、keepalived、haproxy、nginx等,其中LVS属于4层(网络OSI 7层模型),nginx属于7层,haproxy既能够认为是4层,也能够当作7层使用。nginx
LVS:4层的负载均衡是能够分发除80外的其余端口通讯的,例如MySQL的3306端口,而nginx仅仅支持http,https,mail;算法
haproxy也支持MySQL,相比较LVS这种4层的更稳定,能承受更多的请求,keepalived的负载均衡功能其实就是lvs。vim
而nginx这种7层的更加灵活,能实现更多的个性化需求。后端
商业的负载均衡解决方案稳定性比较好,可是成本很是昂贵,因此以开源的LVS为主。服务器
LVS(Linux Virtual Server)是由国内大牛章文嵩开发的,它是基于Linux2.6内核的,已经有不少年没有更新了。网络
LVS架构中有一个核心角色叫作分发器(Load balance),它用来分发用户的请求,还有诸多处理用户请求的服务器(Real Server,简称rs)。架构
LVS有三种常见的模式:NAT模式、IP Tunnel(IP隧道)模式、DR模式。负载均衡
1、NAT模式 1)这种模式借助iptables的nat表来实现; 2)用户的请求到分发器后,经过预设的iptables规则,把请求的数据包转发到后端的rs上去; 3)rs须要设定网关为分发器的内网ip; 4)用户请求的数据包和返回给用户的数据包所有通过分发器,因此分发器成为瓶颈; 5)在nat模式中,只须要分发器有公网ip便可,因此比较节省公网ip资源;
2、IP Tunnel模式 1)这种模式,须要有一个公共的IP配置在分发器和全部rs上,咱们把它叫作vip; 2)客户端请求的目标IP为vip,分发器接收到请求数据包后,会对数据包作一个加工,会把目标IP改成rs的IP,这样数据包就到了rs上; 3)rs接收数据包后,会还原原始数据包,这样目标IP为vip,由于全部rs上配置了这个vip,因此它会认为是它本身; 调度器(Load Balancer)将请求报文封装在另外一个IP报文中,再将封装后的IP报文转发给真实服务器。真实服务器收到报文后,先将报文解封得到原来目标地址为VIP的报文,服务器发现VIP地址被配置在本地的IP隧道设备上,全部就处理这个请求,而后根据路由表将响应报文直接返回给客户。这种模式下,须要给调度器和全部的真实服务器所有分配公网IP,全部比较浪费公网IP。
DR模式 1)这种模式,也须要有一个公共的IP配置在分发器和全部rs上,也就是vip; 2)和IP Tunnel不一样的是,它会把数据包的MAC地址修改成rs的MAC地址; 3)rs接收数据包后,会还原原始数据包,这样目标IP为vip,由于全部rs上配置了这个vip,因此它会认为是它本身;
NAT模式适合小型的集群,机器数量很少,它的优点是节省公网IP。而IP Tunnel和DR相差不大,都能支撑较大规模的集群,但缺点是浪费公网IP。curl
调度器把客户端发来的请求均衡地分发给后端的真实服务器,这是依靠预先设定好的调度算法实现的,在LVS中支持的调度算法主要有如下8种;函数
一、 轮询调度(Round-Robin-rr)
很是简单的一种调度算法,就是按顺序把请求一次发送给后端的服务器,它无论后端服务器的处理速度和相应时间怎样。但当后端服务器性能不一致时,用这种调度算法就不合适了;
二、 加权轮询(Weight Round-Robin-wrr)
比第一种算法多了一个权重的设置,权重越高的服务器被分配到的请求就越多,这样后端服务器性能不一致时,就能够给配置低的服务器较小的权重;
三、 最小链接(Least-Connection-lc)
这种算法会根据各真实服务器上的链接数来决定把新的请求分配给谁,链接数越少说明服务器是空闲的,这样把新的请求分配到空闲服务器上才更加合理;
四、 加权最小链接(Weight Least-Connection-wlc)
在最小链接调度的基础上再增长一个权重设置,这样就能够人为地去控制哪些服务器上多分配请求,哪些少分配请求;
五、 基于局部性的最小链接(Locality-Based Least Connections-lblc)
是针对请求报文的目标IP地址的负载均衡调度,目前主要用于Cache集群系统,由于在Cache集群中客户请求报文的目标IP地址使变化的。算法设计的穆鸟是在服务器的负载在基本平衡的状况下,将相同目标IP的请求调度到同一台服务器,来提升各台服务器的访问局部性和贮存Cache命中率;
六、 带复制的基于局部性最小链接(Locality-Based Least Connections with Replication-lblcr)
也是针对目标IP地址的负载均衡,它与LBLC算法的不一样之处是:它要维护从一个目标IP地址到一组服务器的映射,而LBLC算法是维护一个目标IP地址到一台服务器的映射。LBLCR算法先更换请求的目标IP地址找出该目标IP地址对应的服务器组,按“最小链接”原则从该服务器组中选出一台服务器,若服务器没有超载,则将请求发送到该服务器;若服务器超载,则按“最小链接”原则从整个集群中选出一台服务器,将该服务器加入到服务器组中,将请求发送到该服务器。同时,当该服务器组有一段时间没有被修改,将最忙的服务器从服务器组中删除,以下降复制的程度;
七、 目标地址散列调度(Destination Hashing-dh)
该算法也是针对目标IP地址的负载均衡的,但它是一种静态映射算法,经过一个散列(hash)函数讲一个目标IP地址映射到一台服务器。目标地址散列调度算法先根据请求的目标IP地址,做为散列建(hash key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,不然返回空。
八、源地址散列调度(Source Hashing-sh)
该算法正好与目标地址散列调度算法相反,它根据请求的源IP地址,做为散列键从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,不然返回空。它的算法流程与目标地址散列调度算法基本相似,只不过请求的目标IP地址换成请求的源IP地址。
须要准备三台机器:A、B、C
A:做为分发器(调度器),dir角色。 B和C为:后端真正处理事物的服务器,rs角色
一、网段配置:
A设置两张网卡,ens33为内网:192.168.87.12八、ens37为外网(虚拟机仅主机模式):192.168.130.150 B设置一张网卡,ens33为内网:192.168.87.130,网关必须是A的内网ip:192.168.87.128 C设置一张网卡,ens33为内网:192.168.87.132,网关必须是A的内网ip:192.168.87.128
二、安装LVS的核心组件工具:ipvsadm
yum install -y ipvsadm
三、编写脚本并执行:/usr/local/sbin/lvs_nat.sh
[root@nginx ~]# vim /usr/local/sbin/lvs_nat.sh # director 服务器上开启路由转发功能 echo 1 /proc/sys/net/ipv4/ip_forward # 关闭icmp的重定向 echo 0 /proc/sys/net/ipv4/conf/all/send_redirects echo 0 /proc/sys/net/ipv4/conf/default/send_redirects # 注意区分网卡名字,两个网卡分别为ens33和ens37 echo 0 /proc/sys/net/ipv4/conf/ens33/send_redirects //内网 echo 0 /proc/sys/net/ipv4/conf/ens37/send_redirects //外网 # director 设置nat防火墙 iptables -t nat -F iptables -t nat -X iptables -t nat -A POSTROUTING -s 192.168.87.0/24 -j MASQUERADE # director设置ipvsadm IPVSADM='/usr/sbin/ipvsadm' $IPVSADM -C $IPVSADM -A -t 192.168.130.150:80 -s rr $IPVSADM -a -t 192.168.130.150:80 -r 192.168.30.130:80 -m -w 1 $IPVSADM -a -t 192.168.130.150:80 -r 192.168.30.132:80 -m -w 1 [root@nginx ~]# sh /usr/local/sbin/lvs_nat.sh //执行脚本
四、查看配置结果,测试验证:
[root@nginx ~]# 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.130.150:80 rr 192.168.30.130:80 Masq 1 0 18 192.168.30.132:80 Masq 1 0 4 [root@nginx ~]# curl 192.168.130.150 This is RS1 ! [root@nginx ~]# curl 192.168.130.150 This is RS2 ! [root@nginx ~]# curl 192.168.130.150 This is RS1 ! [root@nginx ~]# curl 192.168.130.150 This is RS2 !