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

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
EMR Serverless StarRocks,5000CU*H 48000GB*H
网络型负载均衡 NLB,每月750个小时 15LCU
简介: 转载:https://blog.csdn.net/moonpure/article/details/52839132LVS之一:三种工作模式的优缺点比较(NAT/TUN/DR)一、Virtual server via NAT(VS-NAT)优点:集群中的物理服务器可以使用任何支持TCP/IP操作系统,物理服务器可以分配Internet的保留私有地址,只有负载均衡器需要一个合法的IP地址。

转载: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等。

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

img_e558fe1fc3cebfe87c2cf5af4abecad7.jpe

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模型实现

试验拓扑:

img_43e6e72b8743ed5f396f7f50d8c3e1d0.jpe

img_4638b405f63316c8d863206a37b2f93b.jpe

然后启动各虚拟机,按上述拓扑规划配置好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模式的原理如下(借用别人的图):

img_bcbb38b0e792449b37f2087dd569ec47.png

说明:

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),看能否获取到正确的页面,且同时观察上述窗口的变化。

img_08fd4d297e4ecde40974f9c26faa4a59.png


从上图(为了方便观察,使用了压力测试)可以看出,访问被正常的分担到了两台后端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上切换。如下图:

img_56ecb1f00e18feae2a453f59cc910910.jpe

我们启用持久连接:

[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

相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
目录
相关文章
|
20天前
|
算法 调度 UED
探索操作系统的心脏:调度算法的奥秘与影响
【10月更文挑战第9天】 本文深入探讨了操作系统中至关重要的组件——调度算法,它如同人体的心脏,维持着系统资源的有序流动和任务的高效执行。我们将揭开调度算法的神秘面纱,从基本概念到实际应用,全面剖析其在操作系统中的核心地位,以及如何通过优化调度算法来提升系统性能。
|
6天前
|
算法 大数据 Linux
深入理解操作系统之进程调度算法
【10月更文挑战第24天】本文旨在通过浅显易懂的语言,带领读者深入了解操作系统中的进程调度算法。我们将从进程的基本概念出发,逐步解析进程调度的目的、重要性以及常见的几种调度算法。文章将通过比喻和实例,使复杂的技术内容变得生动有趣,帮助读者建立对操作系统进程调度机制的清晰认识。最后,我们还将探讨这些调度算法在现代操作系统中的应用和发展趋势。
|
22天前
|
算法 调度 UED
深入理解操作系统的进程调度算法
【10月更文挑战第7天】在操作系统的心脏——内核中,进程调度算法扮演着至关重要的角色。它不仅影响系统的性能和用户体验,还直接关系到资源的合理分配。本文将通过浅显易懂的语言和生动的比喻,带你一探进程调度的秘密花园,从最简单的先来先服务到复杂的多级反馈队列,我们将一起见证算法如何在微观世界里编织宏观世界的和谐乐章。
|
24天前
|
存储 算法 固态存储
IO调度算法
【10月更文挑战第5天】IO调度算法
33 3
|
24天前
|
存储 算法 固态存储
IO调度算法
【10月更文挑战第5天】IO调度算法
33 2
|
27天前
|
边缘计算 算法 调度
探究操作系统的心脏:调度算法的进化与影响
【10月更文挑战第2天】 本文深入探讨了操作系统中核心组件——调度算法的历史演变、关键技术突破及其对现代计算的影响。通过详细回顾从单任务到多任务、实时系统及分布式计算环境下调度算法的发展,文章揭示了这些算法如何塑造我们的数字世界,并对未来的趋势进行了展望。不同于传统的摘要,本文特别聚焦于技术细节与实际应用的结合点,为读者提供一幅清晰的技术演进蓝图。
42 4
|
1月前
|
算法 调度 UED
探索操作系统的心脏:进程调度算法
【9月更文挑战第32天】在数字世界的每一次心跳中,都隐藏着一个不为人知的英雄——进程调度算法。它默默地在后台运作,确保我们的命令得到快速响应,应用程序平稳运行。本文将带你走进操作系统的核心,一探进程调度的奥秘,并通过代码示例揭示其背后的智慧。准备好跟随我一起深入这趟技术之旅了吗?让我们开始吧!
|
2月前
|
算法 调度
操作系统的心脏:深入解析进程调度算法
本文旨在深入探讨现代操作系统中的核心功能之一——进程调度。进程调度算法是操作系统用于分配CPU时间片给各个进程的机制,以确保系统资源的高效利用和公平分配。本文将详细介绍几种主要的进程调度算法,包括先来先服务(FCFS)、短作业优先(SJF)、时间片轮转(RR)以及优先级调度(PS)。我们将分析每种算法的基本原理、优缺点及其适用场景。同时,本文还将讨论多级反馈队列(MFQ)调度算法,并探讨这些算法在实际应用中的表现及未来发展趋势。通过深入解析这些内容,希望能够为读者提供对操作系统进程调度机制的全面理解。
|
2月前
|
存储 算法 前端开发
深入理解操作系统:进程调度与优先级队列算法
【9月更文挑战第25天】在操作系统的复杂世界中,进程调度是维持系统稳定运行的核心机制之一。本文将深入探讨进程调度的基本概念,分析不同的进程调度算法,并着重介绍优先级队列算法的原理和实现。通过简洁明了的语言,我们将一起探索如何优化进程调度,提高操作系统的效率和响应速度。无论你是计算机科学的初学者还是希望深化理解的专业人士,这篇文章都将为你提供有价值的见解。
|
2月前
|
人工智能 算法 大数据
探究操作系统的心脏:调度算法的进化与影响
本文深入探讨了操作系统中核心组件——调度算法的发展及其对系统性能的影响。通过分析先来先服务、短作业优先、时间片轮转等传统调度算法,阐述了它们的原理和优缺点。同时,讨论了现代调度算法如多级队列和优先级调度在提高系统响应速度和处理能力方面的作用。文章还探讨了实时系统中的调度挑战,以及如何通过优化调度策略来满足不同应用场景下的性能需求。