美文网首页技术架构
LVS 机制与调度算法(详细)

LVS 机制与调度算法(详细)

作者: SkTj | 来源:发表于2018-05-15 09:07 被阅读114次

    转载:https://blog.csdn.net/moonpure/article/details/52839132

    LVS之一:三种工作模式的优缺点比较(NAT/TUN/DR)

    一、Virtual server via NAT(VS-NAT)

    优点:集群中的物理服务器可以使用任何支持TCP/IP操作系统,物理服务器可以分配Internet的保留私有地址,只有负载均衡器需要一个合法的IP地址。

    缺点:扩展性有限。当服务器节点(普通PC服务器)数据增长到20个或更多时,负载均衡器将成为整个系统的瓶颈,因为所有的请求包和应答包都需要经过负载均衡器再生。假使TCP包的平均长度是536字节的话,平均包再生延迟时间大约为60us(在Pentium处理器上计算的,采用更快的处理器将使得这个延迟时间变短),负载均衡器的最大容许能力为8.93M/s,假定每台物理服务器的平台容许能力为400K/s来计算,负责均衡器能为22台物理服务器计算。

    解决办法:即使是是负载均衡器成为整个系统的瓶颈,如果是这样也有两种方法来解决它。一种是混合处理,另一种是采用Virtual Server via IP tunneling或Virtual Server via direct routing。如果采用混合处理的方法,将需要许多同属单一的RR DNS域。你采用Virtual Server via IP tunneling或Virtual Server via direct routing以获得更好的可扩展性。也可以嵌套使用负载均衡器,在最前端的是VS-Tunneling或VS-Drouting的负载均衡器,然后后面采用VS-NAT的负载均衡器。

    二、Virtual server via IP tunneling(VS-TUN)

    我们发现,许多Internet服务(例如WEB服务器)的请求包很短小,而应答包通常很大。

    优点:负载均衡器只负责将请求包分发给物理服务器,而物理服务器将应答包直接发给用户。所以,负载均衡器能处理很巨大的请求量,这种方式,一台负载均衡能为超过100台的物理服务器服务,负载均衡器不再是系统的瓶颈。使用VS-TUN方式,如果你的负载均衡器拥有100M的全双工网卡的话,就能使得整个Virtual Server能达到1G的吞吐量。

    不足:但是,这种方式需要所有的服务器支持"IP Tunneling"(IP Encapsulation)协议,我仅在Linux系统上实现了这个,如果你能让其它操作系统支持,还在探索之中。

    三、Virtual Server via Direct Routing(VS-DR)

    优点:和VS-TUN一样,负载均衡器也只是分发请求,应答包通过单独的路由方法返回给客户端。与VS-TUN相比,VS-DR这种实现方式不需要隧道结构,因此可以使用大多数操作系统做为物理服务器,其中包括:Linux 2.0.36、2.2.9、2.2.10、2.2.12;Solaris 2.5.1、2.6、2.7;FreeBSD 3.1、3.2、3.3;NT4.0无需打补丁;IRIX 6.5;HPUX11等。

    不足:要求负载均衡器的网卡必须与物理网卡在一个物理段上

    LVS之二:负载均衡调度算法

    前面的文章介绍了LVS的三种模式:NAT、TUN、DR,那这三种模式下,如果进行负载均衡调度计算呢?这就涉及到新的知识点:负载均衡调度算法

    目前LVS主要有三种请求转发方式和10种调度算法。根据请求转发方式的不同,所构架集群的网络拓扑、安装方式、性能表现也各不相同。用LVS主要可以架构三种形式的集群,分别是LVS/NAT、LVS/TUN和LVS/DR,可以根据需要选择其中一种。在选定转发方式的情况下,采用哪种调度算法将决定整个负载均衡的性能表现,不同的算法适用于不同的应用场合,有时可能需要针对特殊场合,自行设计调度算法。LVS的算法是逐渐丰富起来的,最初LVS只提供4种调度算法,后来发展到以下10种。

    一、静态调度算法:

    1.1 轮叫调度(Round Robin,RR)

    调度器通过“轮叫"调度算法将外部请求按顺序轮流分配到集群中的真实服务器上,它均等地对待每一台服务器,而不管服务器上实际的连接数和系统负载。

    1.2 加权轮叫(Weighted Round Robin,WRR)

    调度器通过“加权轮叫"调度算法根据真实服务器的不同处理能力来调度访问请求。这样可以保证处理能力强的服务器能处理更多的访问流量。调度器可以自动问询真实服务器的负载情况,并动态地调整其权值。

    1.3 目标地址散列(Destination Hashing,DH)

    “目标地址散列"调度算法根据请求的目标IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,否则返回空。主要用于缓存服务器的场景。

    1.4 源地址散列(Source Hashing,SH)

    “源地址散列"调度算法根据请求的源IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,否则返回空。在没有使用session共享的又需要保存session的环境下(如电子商务网站),建议使用此算法。

    二、动态调度算法:

    2.1 最少链接(Least Connections,LC)

    调度器通过“最少连接"调度算法动态地将网络请求调度到已建立的链接数最少的服务器上。如果集群系统的真实服务器具有相近的系统性能,采用“最小连接"调度算法可以较好地均衡负载。其具体算法为:

    active*256+inactive

    然后挑选服务器中上述值最小者分配新连接。

    2.2 加权最少链接(Weighted Least Connections,WLC)

    在集群系统中的服务器性能差异较大的情况下,调度器采用“加权最少链接"调度算法优化负载均衡性能,具有较高权值的服务器将承受较大比例的活动连接负载。调度器可以自动问询真实服务器的负载情况,并动态地调整其权值。WLC为LVS的默认调度算法。其具体算法为:

    (active*256+inactive)/weight

    然后挑选服务器根据上述方法计算数字最小者分配新连接。

    2.3 基于局部性的最少链接(Locality-Based Least Connections,LBLC)

    “基于局部性的最少链接"调度算法是针对目标IP地址的负载均衡,目前主要用于Cache集群系统。该算法根据请求的目标IP地址找出该目标IP地址最近使用的服务器,若该服务器是可用的且没有超载,将请求发送到该服务器;若服务器不存在,或者该服务器超载且有服务器处于一半的工作负载,则用“最少链接"的原则选出一个可用的服务器,将请求发送到该服务器。

    类似于DH算法,不同的是,其结合了DH算法和LC算法的优势。

    2.4 带复制的基于局部性最少链接(Locality-Based Least Connections with Replication,LBLCR)

    “带复制的基于局部性最少链接"调度算法也是针对目标IP地址的负载均衡,目前主要用于Cache集群系统。它与LBLC算法的不同之处是它要维护从一个目标IP地址到一组服务器的映射,而LBLC算法维护从一个目标IP地址到一台服务器的映射。该算法根据请求的目标IP地址找出该目标IP地址对应的服务器组,按“最小连接"原则从服务器组中选出一台服务器,若服务器没有超载,将请求发送到该服务器;若服务器超载,则按“最小连接"原则从这个集群中选出一台服务器,将该服务器加入到服务器组中,将请求发送到该服务器。同时,当该服务器组有一段时间没有被修改,将最忙的服务器从服务器组中删除,以降低复制的程度。

    2.5 最短的期望的延迟(Shortest Expected Delay Scheduling,SED)

    “最短的期望的延迟”是基于WLC算法的,只是其计算方法不同。具体算法如下:

    (active+1)*256/weight

    2.6 最少队列(Never Queue Scheduling,NQ)

    无需队列。如果有台 realserver的连接数=0就直接分配过去,不需要在进行SED运算。如果没有服务器连接数为空闲,则使用SED算法。

    了解这些算法原理能够在特定的应用场合选择最适合的调度算法,从而尽可能地保持Real Server的最佳利用性。

    LVS之三:ipvsadm常用管理命令介绍

    LVS全称为Linux Virtual Server,工作在ISO模型中的第四层,由于其工作在第四层,因此与iptables类似,必须工作在内核空间上。因此lvs与iptables一样,是直接工作在内核中的,叫ipvs,主流的linux发行版默认都已经集成了ipvs,因此用户只需安装一个管理工具ipvsadm即可。

    查看内核是否已经集成ipvs:

    [root@lvs ~]# grep -i "ip_vs" /boot/config-2.6.32-358.18.1.el6.x86_64

    CONFIG_IP_VS=m

    CONFIG_IP_VS_IPV6=y

    # 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_AH_ESP=y

    CONFIG_IP_VS_PROTO_ESP=y

    CONFIG_IP_VS_PROTO_AH=y

    CONFIG_IP_VS_PROTO_SCTP=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

    一、安装ipvsadm:

    [root@lvs ~]# yum -y install ipvsadm

    二、ipvsadm基本介绍:

    2.1 集群服务管理类命令:

    2.1.1 添加集群:

    # ipvs -A -t|u|f service-address [-s scheduler]

    选项说明:

    -t: TCP协议的集群

    -u: UDP协议的集群

    service-address:     IP:PORT

    -f: FWM: 防火墙标记

    service-address: Mark Number

    示例:

    [root@lvs ~]# ipvsadm -A -t 172.16.1.253:80 -s wlc

    2.1.2 修改集群:

    # ipvs -E -t|u|f service-address [-s scheduler]

    示例:

    [root@lvs ~]# ipvsadm -E -t 172.16.1.253:80-s wrr

    2.1.3 删除集群:

    # ipvsadm -D -t|u|f service-address

    示例:

    [root@lvs ~]# ipvsadm -D -t 172.16.1.253:80

    2.2 管理集群中的RealServer:

    2.2.1 添加RS:

    # ipvsadm -a -t|u|f service-address -r server-address [-g|i|m] [-w weight]

    选项说明:

    -t|u|f service-address:事先定义好的某集群服务

    -r server-address: 某RS的地址,在NAT模型中,可使用IP:PORT实现端口映射;

    [-g|i|m]: LVS类型

    -g: DR

    -i: TUN

    -m: NAT

    [-w weight]: 定义服务器权重

    示例:

    [root@lvs ~]# ipvsadm -a -t 172.16.1.253:80 -r 172.16.1.101 –g -w 5

    [root@lvs ~]# ipvsadm -a -t 172.16.1.253:80 -r 172.16.1.102 –g -w 10

    2.2.2 修改RS:

    # ipvsadm -e -t|u|f service-address -r server-address [-g|i|m] [-w weight]

    示例:

    [root@lvs ~]# ipvsadm-e-t 172.16.1.253:80 -r 172.16.1.101 –g -w3

    2.2.3 删除RS:

    # ipvsadm -d -t|u|f service-address -r server-address

    示例:

    [root@lvs ~]# ipvsadm -d -t 172.16.1.253:80 -r 172.16.1.101

    2.3 查看类:

    # ipvsadm -L|l [options]

    常用选项[options]如下:

    -n: 数字格式显示主机地址和端口

    --stats:统计数据

    --rate: 速率

    --timeout: 显示tcp、tcpfin和udp的会话超时时长

    -c: 显示当前的ipvs连接状况

    2.4 其他管理类:

    2.4.1 删除所有集群服务:

    # ipvsadm -C

    该命令与iptables的-F功能类似,执行后会清除所有规则。

    2.4.2 保存规则

    保存规则至默认配置文件:

    # service ipvsadm save

    保存规则至指定文件:

    # ipvsadm -S > /path/to/somefile

    示例:

    [root@lvs ~]# service ipvsadm save

    ipvsadm: Saving IPVS table to /etc/sysconfig/ipvsadm:      [确定]

    2.4.3 载入保存在文件中的规则

    # ipvsadm -R < /path/form/somefile

    三、lvs的其他注意事项:

    关于时间同步:各节点间的时间偏差不大于1s,建议使用统一的ntp服务器进行更新时间;

    DR模型中的VIP的MAC广播问题:

    在DR模型中,由于每个节点均要配置VIP,因此存在VIP的MAC广播问题,在现在的linux内核中,都提供了相应kernel 参数对MAC广播进行管理,具体如下:

    arp_ignore: 定义接收到ARP请求时的响应级别;

    0:只要本地配置的有相应地址,就给予响应;

        1:仅在请求的目标地址配置在到达的接口上的时候,才给予响应;DR模型使用

    arp_announce:定义将自己地址向外通告时的通告级别;

    0:将本地任何接口上的任何地址向外通告;

    1:试图仅向目标网络通告与其网络匹配的地址;

        2:仅向与本地接口上地址匹配的网络进行通告;DR模型使用

    LVS之四:DR模型实现

    试验拓扑:

    然后启动各虚拟机,按上述拓扑规划配置好IP地址。

    1.2 配置路由器(linux):

    使用iptables实现NAT配置较为简单,主要如下:

    1.2.1 开启转发功能:

    [root@router ~]# echo 1 >/proc/sys/net/ipv4/ip_forward

    如果需永久修改,则需要修改sysctl.conf文件。并使用sysctl -p 使其立即生效。

    1.2.2 配置iptables:

    清除所有规则:

    [root@router ~]# iptables –F

    配置NAT功能:

    [root@router ~]# iptables -t nat -A POSTROUTING -o eth0 -s 172.16.1.0/24 -j SNAT --to 192.168.8.254

    [root@router ~]# iptables -t nat -A PREROUTING -d 192.168.8.254 -p tcp --dport 80 -j DNAT --to-destination 172.16.1.253:80

    ##为了方便使用ssh客户端连接,我还将lvs集群中各服务器的22端口映射到了不同端口,具体如下:

    [root@router ~]# iptables -t nat -A PREROUTING -d 192.168.8.254 -p tcp --dport2022-j DNAT --to-destination172.16.1.252:22

    [root@router ~]# iptables -t nat -A PREROUTING -d 192.168.8.254 -p tcp --dport2122-j DNAT --to-destination172.16.1.101:22

    [root@router ~]# iptables -t nat -A PREROUTING -d 192.168.8.254 -p tcp --dport2222-j DNAT --to-destination172.16.1.102:22

    配置转发功能:

    [root@router ~]# iptables -A FORWARD -p ip -j ACCEPT

    保存规则:

    [root@router ~]# service iptables save

    此时,Director和RealServer都已可以正常访问外网。

    1.3 配置本地windows,添加路由使其能访问lvs集群:

    由于试验中物理主机(windows)和试验用路由器(linux)的默认网关指向的是真实的路由器,因此物理主机(windows)是无法访问lvs集群网络的,为了能让物理机(windows)访问到集群网络方便后面测试,因此需要添加路由,命令如下:

    C:\windows\system32>route add 172.16.1.0/24 192.168.8.254

    操作完成!

    二、配置Director

    2.1 启用转发:

    [root@lvs ~]# echo 1 > /proc/sys/net/ipv4/ip_forward

    如果想永久生效,则需要修改/etc/sysctl.conf文件。

    2.2 配置VIP和路由:

    配置路由:

    [root@lvs ~]# route add -host 172.16.1.253 dev eth0:0

    配置VIP:

    [root@lvs ~]# ifconfig eth0:1 172.16.1.253 netmask 255.255.255.255 up

    2.3 清除原有iptables和ipvs规则:

    [root@lvs ~]# iptables -F

    [root@lvs ~]# iptables -Z

    [root@lvs ~]# ipvsadm -C

    2.4 配置集群服务:

    [root@lvs ~]# ipvsadm -A -t 172.16.1.253:80 -s wlc

    2.5 添加RS至集群服务:

    [root@lvs ~]# ipvsadm -a -t 172.16.1.253:80 -r 172.16.1.101 -g

    [root@lvs ~]# ipvsadm -a -t 172.16.1.253:80 -r 172.16.1.102 -g

    2.6 将上述过程编写为一个服务脚本,直接在Director上实现开机启动:

    #!/bin/bash

    #

    # LVS script for VS/DR

    # chkconfig: - 90 10

    #

    . /etc/rc.d/init.d/functions

    #

    VIP=172.16.1.253

    DIP=172.16.1.252

    RIP1=172.16.1.101

    RIP2=172.16.1.102

    PORT=80

    RSWEIGHT1=5

    RSWEIGHT2=5

    #

    case "$1" in

    start)

    /sbin/ifconfig eth0:1 $VIP broadcast $VIP netmask 255.255.255.255 up

    /sbin/route add -host $VIP dev eth0:1

    # Since this is the Director we must be able 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 VIP 192.168.0.219 port 80

    # In this recipe, we will use the round-robin scheduling method.

    # In production, however, you should use a weighted, dynamic scheduling method.

    /sbin/ipvsadm -A -t $VIP:80 -s wlc

    # Now direct packets for this VIP to

    # the real server IP (RIP) inside the cluster

    /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

    将上述内容保存在/etc/init.d/lvs-director文件中,然后添加到服务:

    [root@lvs ~]# chmod +x /etc/init.d/lvs-director

    [root@lvs ~]# chkconfig --add lvs-director

    [root@lvs ~]# chkconfig lvs-director on

    [root@lvs ~]# /etc/init.d/lvs-director start

    [root@lvs ~]# /etc/init.d/lvs-director status

    ipvs is running ...

    IP Virtual Server version 1.2.1 (size=4096)

    Prot LocalAddress:Port Scheduler Flags

    -> RemoteAddress:Port           Forward Weight ActiveConn InActConn

    TCP  172.16.1.253:80 wlc

    -> 172.16.1.101:80              Route   5      0          0

    -> 172.16.1.102:80              Route   5      0          0

    三、配置RS:

    3.1 配置ARP广播:

    [root@rs1 ~]# echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore

    [root@rs1 ~]# echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce

    [root@rs1 ~]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore

    [root@rs1 ~]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce

    3.2 配置VIP和路由:

    [root@rs1 ~]# ifconfig lo:0 172.16.1.253 netmask 255.255.255.255 up

    [root@rs1 ~]# route add -host 172.16.1.253 dev lo:0

    3.3 编写为脚本:

    #!/bin/bash

    #

    # Script to start LVS DR real server.

    # chkconfig: - 90 10

    # description: LVS DR real server

    #

    .  /etc/rc.d/init.d/functions

    VIP=172.16.1.253

    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

    保存至/etc/init.d/lvs-rs,并赋予执行权限,然后添加为开机启动:

    [root@rs1~]# chmod +x /etc/init.d/lvs-rs

    [root@rs1 ~]# chkconfig --add lvs-rs

    [root@rs1 ~]# chkconfig lvs-rs on

    [root@rs1 ~]# /etc/init.d/lvs-rs start

    3.4 在RS2上采用相同的配置即可

    至此就全部完成了lvs的DR模型配置。

    4 测试LVS集群

    4.1 配置web服务器:

    4.1.1 为rs1节点添加web主页:

    [root@rs1 ~]# service httpd start

    正在启动 httpd:httpd: apr_sockaddr_info_get() failed for rs1

    httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName

    [确定]

    [root@rs1 ~]# echo "This is RS1..." >/var/www/html/index.html

    4.1.2 为rs2节点添加web主页:

    [root@rs2 ~]# echo "This is RS2..." >/var/www/html/index.html

    4.2 访问测试:

    访问时观察ipvs状态:

    Every 1.0s: ipvsadm -L -n                                                                        Tue Oct  8 19:58:42 2013

    IP Virtual Server version 1.2.1 (size=4096)

    Prot LocalAddress:Port Scheduler Flags

    -> RemoteAddress:Port           Forward Weight ActiveConn InActConn

    TCP  172.16.1.253:80 wlc

    -> 172.16.1.101:80              Route   5     2          8

    -> 172.16.1.102:80              Route   5     1          8

    LVS之五:使用脚本实现RealServer的健康检查

    上文部署的DR模型中,当一台RS宕机时,ipvs是不会自动踢出该RS服务器的,我这里使用一个脚本实现对RS的监控检查。

    一、需求分析:

    脚本要能判断RS运行情况;

    当RS的web服务不能访问时,将其从lvs集群中踢出;而当RS重新上线时,再将其加入lvs集群;

    定时检查(死循环或cron计划任务);

    对RS的下线和上线做日志记录。

    二、web健康检查命令:

    使用curl能简单的实现对web应用可用性进行监控:

    curl命令选项:

    --cacert CA证书 (SSL)

    --capath CA目录 (made using c_rehash) to verify peer against (SSL)

    --compressed 要求返回是压缩的形势 (using deflate or gzip)

    --connect-timeout 设置最大请求时间

    -H/--header 自定义头信息传递给服务器

    -i/--include 输出时包括protocol头信息

    -I/--head 只显示文档信息

    --interface 使用指定网络接口/地址

    -s/--silent静音模式。不输出任何东西

    -u/--user 设置服务器的用户和密码

    -p/--proxytunnel 使用HTTP代理

    三、具体实现:

    #!/bin/bash

    #

    VIP=192.168.8.254

    CPORT=80

    ##使用数组RS定义所有RS服务器

    RS=("172.16.1.101" "172.16.1.102")

    #定义RS状态,后面引用

    declare -a RSSTATUS

    #定义权重

    RW=("5" "5")

    RPORT=80

    #集群类型为DR

    TYPE=g

    CHKLOOP=3

    #监控日志

    LOG=/var/log/ipvsmonitor.log

    #

    #addrs函数在RS重新上线时将其添加到集群

    addrs() {

    ipvsadm -a -t $VIP:$CPORT -r $1:$RPORT -$TYPE -w $2

    [ $? -eq 0 ] && return 0 || return 1

    }

    #delrs函数在RS下线时将其从集群中删除

    delrs() {

    ipvsadm -d -t $VIP:$CPORT -r $1:$RPORT

    [ $? -eq 0 ] && return 0 || return 1

    }

    #checkrs检查RS状态,如果上次均为离线状态,则判定其为离线

    checkrs() {

    local I=1

    while [ $I -le $CHKLOOP ]; do

    if curl --connect-timeout 1http://$1&> /dev/null; then

    return 0

    fi

    let I++

    done

    return 1

    }

    #初始化RS状态函数

    initstatus() {

    local I

    local COUNT=0;

    for I in ${RS[*]}; do

    if ipvsadm -L -n | grep "$I:$RPORT" && > /dev/null ; then

    RSSTATUS[$COUNT]=1

    else

    RSSTATUS[$COUNT]=0

    fi

    let COUNT++

    done

    }

    #执行初始化RS状态检查函数

    initstatus

    #死循环

    while :; do

    let COUNT=0

    for I 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 is back." >> $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

    LVS之六:使用keepalived实现LVS的DR模式热备

    一、说明:

    在《LVS之一:三种工作模式的优缺点比较(NAT/TUN/DR)》文章讲述了LVS的三种转发模式对比,我们先就用LVS的DR模式来实现Web应用的负载均衡。为了防止LVS服务器自身的单点故障导致整个Web应用无法提供服务,因此还得利用Keepalived实现lvs的高可用性,keepalived主要使用VRRP协议来保存链路的高可用性。而VRRP(Virtual Router Redundancy Protocol)协议本身是用于实现路由器冗余的协议。

    LVS-DR模式的原理如下(借用别人的图):

    说明:

    1、  LVS服务器和WEB服务器必须在同一网段;

    2、  多台Web服务器间使用NFS服务器等共享存储存放用户上传附件,以保障数据的一致性(如上传图片)。下文讨论

    IP地址规划:

    VIP              192.168.18.60

    LVS-MASTER     192.168.18.51

    LVS-BACKUP     192.168.18.52

    NFS   Server       192.168.18.20

    MySQL               192.168.18.18

    WEB1        192.168.18.61

    WEB2        192.168.18.62

    三、安装LVS+Keepalived:

    1、使用yum在线安装:

    [root@lvs1 ~]# yum install ipvsadm  keepalived –y

    2、检查安装结果:

    [root@lvs1 ~]# rpm -qa |grep ipvsadm

    ipvsadm-1.25-10.el6.x86_64

    [root@lvs1 ~]# rpm -qa |grep keepalived

    keepalived-1.2.7-3.el6.x86_64

    3、服务配置:

    [root@lvs1 ~]# chkconfig keepalived on   ##设置为开机启动

    [root@lvs1 ~]# service keepalived start   ##立即启动keepalived服务

    四、配置LVS服务器:

    1、  备份配置文件:

    [root@lvs1 ~]# cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.bak

    2、  修改配置文件,具体如下:

    原始的配置文件包含了三种模式的配置,而这里我们只需要用到DR模式,因此最终保留配置如下:

    [root@lvs1 ~]#  vim /etc/keepalived/keepalived.conf

    global_defs {                       ##全局配置部分

    #   notification_email {             ##下面几行均为全局通知配置,可以实现出现问题后报警,但功能有限,因此注释掉,并采用Nagios监视lvs运行情况

    #       admin@toxingwang.com

    #   }

    #   notification_email_from master@toxingwang.com

    #   smtp_server smtp.exmail.qq.com

    #   smtp_connect_timeout 30

    router_id LVS_MASTER             ##设置lvs的id,在一个网络内应该是唯一的

    }

    vrrp_instance VI_1 {            ##设置vrrp组,唯一且同一LVS服务器组要相同

    stateMASTER  ##备份LVS服务器设置为BACKUP

    interface eth0             # #设置对外服务的接口

    virtual_router_id 51        ##设置虚拟路由标识

    priority 100                                    #设置优先级,数值越大,优先级越高,backup设置为99,这样就能实现当master宕机后自动将backup变为master,而当原master恢复正常时,则现在的master再次变为backup。

    advert_int 1            ##设置同步时间间隔

    authentication {         ##设置验证类型和密码,master和buckup一定要设置一样

    auth_type PASS

    auth_pass 1111

    }

    virtual_ipaddress {          ##设置VIP,可以多个,每个占一行

    192.168.18.60

    }

    }

    virtual_server 192.168.18.60 80 {

    delay_loop 6            ##健康检查时间间隔,单位s

    lb_algo wrr             ##负载均衡调度算法设置为加权轮叫

    lb_kind DR                              ##负载均衡转发规则

    nat_mask 255.255.255.0   ##网络掩码,DR模式要保障真是服务器和lvs在同一网段

    persistence_timeout 50    ##会话保持时间,单位s

    protocol TCP                           ##协议

    real_server 192.168.18.61 80 {      ##真实服务器配置,80表示端口

    weight 3                              ##权重

    TCP_CHECK {                       ##服务器检测方式设置

    connect_timeout 5    ##连接超时时间

    nb_get_retry 3

    delay_before_retry 3

    connect_port 80

    }

    }

    real_server 192.168.18.62 80 {

    weight 3

    TCP_CHECK {

    connect_timeout 10

    nb_get_retry 3

    delay_before_retry 3

    connect_port 80

    }

    }

    }

    作为高可用的备份lvs服务器配置只需在上述配置中的master修改backup即可,其他保持相同。

    3、  分别在两台lvs服务器上重启服务:

    [root@lvs1 ~]# service keepalived start

    注:由于keepalived配置文件有语法错误也能启动,因此看到启动了lvs服务,不代表配置文件没有错误,如果遇到lvs不能正常转发,及时跟踪日志进行处理。

    日志跟踪方法:

    1、开两个ssh窗口连接到lvs服务器,第一个窗口运行如下命令:

    [root@lvs1 ~]# tail -F /var/log/message

    2、第二个窗口重新启动keepalived服务,同时观察窗口1中日志的变化,然后根据日志提示解决即可。

    五、WEB服务器IP绑定配置:

    在两台WEB服务器安装并配置(非本文重点,不做web安装配置讲解),建立测试网页,先使用实际IP进行访问测试,能正常访问后,进行如下操作:

    在前面的文章中介绍DR模式时提到:负载均衡器也只是分发请求,应答包通过单独的路由方法返回给客户端。但实际上客户端访问时,IP都是指向的负载均衡器的ip(也就是LVS的VIP),如何能让真是服务器处理IP头为VIP的请求,这就需要做下面的操作,将VIP绑定到真实服务器的lo网口(回环),为了防止IP广播产生IP冲突,还需关闭IP广播,具体如下:

    1、编辑开机启动脚本:

      [root@web1 ~]# vim /etc/init.d/realserver

    #!/bin/bash

    #chkconfig: 2345 79 20

    #description:realserver

    SNS_VIP=192.168.18.60

    . /etc/rc.d/init.d/functions

    case "$1" in

    start)

    ifconfig lo:0 $SNS_VIP netmask 255.255.255.255 broadcast $SNS_VIP

    /sbin/route add -host $SNS_VIP dev lo:0

    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

    sysctl -p >/dev/null 2>&1

    echo "RealServer Start OK"

    ;;

    stop)

    ifconfig lo:0 down

    route del $SNS_VIP >/dev/null 2>&1

    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

    echo "RealServer Stoped"

    ;;

    *)

    echo "Usage: $0 {start|stop}"

    exit 1

    esac

    exit 0

    脚本说明:

    arp_ignore: 定义接收到ARP请求时的响应级别;

    0:只要本地配置的有相应地址,就给予响应;默认;

    1:仅在请求的目标地址配置在到达的接口上的时候,才给予响应;

    arp_announce:定义将自己地址向外通告时的通告级别;

    0:将本地任何接口上的任何地址向外通告;默认;

    1:试图仅向目标网络通告与其网络匹配的地址;

    2:仅向与本地接口上地址匹配的网络进行通告;

    2、  设置脚本开机启动并立即启动:

    [root@web1 ~]# chkconfig realserver on

    [root@web1 ~]# service realserver start

    RealServer Start OK

    3、  检测IP配置:

    [root@web1 ~]# ifconfig

    eth0      Link encap:Ethernet  HWaddr 00:50:56:B3:54:5A

    inet addr:192.168.18.61  Bcast:192.168.18.255  Mask:255.255.255.0

    inet6 addr: fe80::250:56ff:feb3:545a/64 Scope:Link

    UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

    RX packets:98940 errors:4 dropped:4 overruns:0 frame:0

    TX packets:82037 errors:0 dropped:0 overruns:0 carrier:0

    collisions:0 txqueuelen:1000

    RX bytes:23077218 (22.0 MiB)  TX bytes:16043349 (15.3 MiB)

    Interrupt:18 Base address:0x2000

    lo        Link encap:Local Loopback

    inet addr:127.0.0.1  Mask:255.0.0.0

    inet6 addr: ::1/128 Scope:Host

    UP LOOPBACK RUNNING  MTU:16436  Metric:1

    RX packets:300 errors:0 dropped:0 overruns:0 frame:0

    TX packets:300 errors:0 dropped:0 overruns:0 carrier:0

    collisions:0 txqueuelen:0

    RX bytes:528420 (516.0 KiB)  TX bytes:528420 (516.0 KiB)

    lo:0      Link encap:Local Loopback

    inet addr:192.168.18.60 Mask:255.255.255.255

    UP LOOPBACK RUNNING  MTU:16436  Metric:1

    4、  测试LVS:

    在lvs master服务器上运行如下命令:

    [root@lvs1 ~]# watch -n 1 ipvsadm -ln

    在多台客户端通过浏览器访问VIP或域名(域名需解析到VIP),看能否获取到正确的页面,且同时观察上述窗口的变化。

    从上图(为了方便观察,使用了压力测试)可以看出,访问被正常的分担到了两台后端web服务器 。

    六、后继问题探讨:

    1、用户新上传的附件存放问题;目前我们采用的是NFS方式解决,但存在单点故障,需要配合其他方式解决。NFS的基本用法请参考《NFS的配置和使用

    2、后端数据库高可用性;

    3、会话共享和保持问题(Session共享);算法调整为SH可解决,但有RealServer宕机时,其上的session也会丢失。后期将调整为实现共享session。

    LVS之七:使用持久连接解决session问题

    前面在讨论LVS算法中,SH算法可以实现将同一客户端的请求总是发送给第一次指定的RS,除非该RS出现故障不能再提供服务。其实在LVS集群中,持久连接功能也能在一定时间内,将来自同一个客户端请求派发至此前选定的RS,而且是无关算法的。

    持久连接的三种类型:

    在基于SSL的加密https协议中,特别需要用到持久连接,因为客户端需要与服务器进行交换证书并协商加密算法等。

    如果一个集群中提供了两种服务,持久连接会将同一客户端的所有请求都同步到同一RS。持久连接分三种:

    PPC(持久端口连接):将来自于同一个客户端对同一个集群服务的请求,始终定向至此前选定的RS;

    PCC(持久客户端连接):将来自于同一个客户端对所有端口的请求,始终定向至此前选定的RS;PCC是把所有端口统统定义为集群服务,一律向RS转发;

    PNMPP:持久防火墙标记连接。使用iptables的标记功能,可以实现给多个服务(端口)打上相同的标记,然后在ipvsadm使用-f选项,并使用上述防火墙标记即可将多个服务放到一个LVS集群中。实现过程如下:

    # iptables -t mangle -A PREROUTING -d 192.168.8.253 -p tcp --dport 80 -i $INCARD -j MARK --set-mark10

    # iptables -t mangle -A PREROUTING -d 192.168.8.253 -p tcp --dport 443 -i $INCARD -j MARK --set-mark10

    # ipvsadm -A -f10-s wlc –p 600

    持久连接模板查看:

    LVS的持久连接又集群的持久连接模板(一个内存缓冲区)提供;该持久连接模板保存着每一个客户端及分配给它的RS的映射关系。使用如下命令可以查看该模板:

    [root@lvs ~]#ipvsadm -L -c

    IPVS connection entries

    pro expire state       source             virtual            destination

    TCP 01:56  FIN_WAIT    192.168.8.12:51822 172.16.1.253:http  172.16.1.102:http

    TCP 01:57  FIN_WAIT    192.168.8.12:51825 172.16.1.253:http  172.16.1.101:http

    TCP 01:56  FIN_WAIT    192.168.8.12:51821 172.16.1.253:http  172.16.1.101:http

    TCP 01:42  FIN_WAIT    192.168.8.12:51814 172.16.1.253:http  172.16.1.102:http

    TCP 01:57  FIN_WAIT    192.168.8.12:51826 172.16.1.253:http  172.16.1.102:http

    TCP 01:57  FIN_WAIT    192.168.8.12:51824 172.16.1.253:http  172.16.1.102:http

    TCP 01:56  FIN_WAIT    192.168.8.12:51820 172.16.1.253:http  172.16.1.102:http

    TCP 14:58  ESTABLISHED 192.168.8.12:51828 172.16.1.253:http  172.16.1.102:http

    TCP 01:55  FIN_WAIT    192.168.8.12:51815 172.16.1.253:http  172.16.1.101:http

    TCP 01:56  FIN_WAIT    192.168.8.12:51823 172.16.1.253:http  172.16.1.101:http

    TCP 01:57  FIN_WAIT    192.168.8.12:51827 172.16.1.253:http  172.16.1.101:http

    配置并启用lvs集群的持久连接:

    基本语法:

    ipvsadm -A|E ... -p timeout

    timeout: 持久连接时长,默认300秒;单位是秒;

    在使用《LVS之四:DR模型实现》中的lvs集群,每次刷新客户端时,都会在RS1和RS2上切换。如下图:

    我们启用持久连接:

    [root@lvs ~]# ipvsadm -L -n

    IP Virtual Server version 1.2.1 (size=4096)

    Prot LocalAddress:Port Scheduler Flags

    -> RemoteAddress:Port           Forward Weight ActiveConn InActConn

    TCP  172.16.1.253:80 wlc

    -> 172.16.1.101:80              Route   5      0          1

    -> 172.16.1.102:80              Route   5      0          2

    [root@lvs ~]# ipvsadm -E -t 172.16.1.253:80 -p 600

    [root@lvs ~]# ipvsadm -L -n

    IP Virtual Server version 1.2.1 (size=4096)

    Prot LocalAddress:Port Scheduler Flags

    -> RemoteAddress:Port           Forward Weight ActiveConn InActConn

    TCP  172.16.1.253:80 wlc persistent 600

    -> 172.16.1.101:80              Route   5      0          0

    -> 172.16.1.102:80              Route   5      0          1

    此时再次刷新客户端,会发现已经不会再改变RS。

    [root@lvs ~]# ipvsadm -L --persistent-conn

    IP Virtual Server version 1.2.1 (size=4096)

    Prot LocalAddress:Port            Weight    PersistConn ActiveConn InActConn

    -> RemoteAddress:Port

    TCP  172.16.1.253:http wlc persistent 600

    -> 172.16.1.101:http            5         0           0          0

    ->172.16.1.102:http            5         1           0          14

    相关文章

      网友评论

        本文标题:LVS 机制与调度算法(详细)

        本文链接:https://www.haomeiwen.com/subject/btfedftx.html