本博客的最终目标的讲解:
由于lvs的十种调度算法(大部分基于连接数)没有把真实服务器的负载, cpu Idle, 和swap等信息算进去, 而这些参数又是一个真实服务器能否给用户良好体验的重要参数, 因此, 我们在真实的环境下要把这些信息回馈给调度器, 让调度器更好的调度群集服务器.
本文章主要实现: 当负载, cpu Idle, swap的使用率不符合我们的意愿时, 调度器将真实服务器从负载均衡群集中移除出来; 当负载, cpu Idle, swap的使用率符合的我们的意愿时, 再将真实服务器添加进来. (参数临界值自己定义)
实现目标的具体思路讲解:
1; 使用shell收集真实服务器的负载, cpu Idle, swap信息, 并将信息定时反馈给调度器.
2; 使用keepalived提供的MISC_CHECK的健康检查方式, 自己编写脚本查看各台真实服务器的负载, cpu Idle, swap信息. 当全部都没有超过临界值时返回0(代表真实服务器加入群集), 当有其中的一个选项超过临界值时返回1(代表真实服务器移除群集);
一: 实验环境的介绍(看不懂的可以先看看本人以前写的一篇关于lvs负载均衡的博客, );
1: 调度器:
ip地址: 192.168.2.49
安装的软件: ipvsadm+keepalived
keepalived的配置文件如下:
[php]
! configuration file for keepalived
global_defs {
notification_email{
361589194@qq.com
}
notification_email_from 361589194@qq.com
smtp_server smtp.163.com
router_id lvs_director #must different with backup
}
vrrp_instance V1{
state MASTER
interface eth0
lvs_sync_daemon_interface eth0
virtual_router_id 51 #must the same as backup
priority 150 #normally backup low 50
advert_int 5
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.2.149
}
}
virtual_server 192.168.2.149 80 {
delay_loop 10
lb_algo wrr
lb_kind DR
#persistence_timeout 10
protocol TCP
real_server 192.168.2.51 80 {
weight 100
MISC_CHECK {
misc_path "/data/linux/shell/check51.sh"
misc_timeout 30
misc_dynamic
}
}
real_server 192.168.2.52 80 {
weight 100
MISC_CHECK {
misc_path "/data/linux/shell/check52.sh"
misc_timeout 30
misc_dynamic
}
#TCP_CHECK {
# connect_timeout 10
# nb_get_retry 3
# delay_before_retry 3
# connect_port 80
#}
}
}
[/php]
2: 真实服务器:
IP地址: 192.168.2.51, 192.168.2.52
真实服务器的shell脚本如下(主要是DR模式为了避免mac欺骗):
[php]
#/bin/bash
#program:
# script to start lvs, stop lvs, show lvs status;
#history;
#2013/3/29 whzhuang first release
VIP=192.168.2.149
DEV=lo
case "$1" in
start)
/sbin/ifconfig $DEV down
/sbin/ifconfig $DEV up
#echo 1 > /proc/sys/net/ipv4/conf/$DEV/arp_filter
#echo 1 > /proc/sys/net/ipv4/conf/all/arp_filter
echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/$DEV/rp_filter
echo 1 > /proc/sys/net/ipv4/conf/$DEV/arp_ignore
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/$DEV/arp_announce
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
/sbin/ifconfig $DEV:0 $VIP broadcast $VIP netmask 255.255.255.255 up
/sbin/route add -host $VIP dev $DEV:0
echo "lvs dr model real server is running..."
;;
stop)
/sbin/ifconfig $DEV:0 down &> /dev/null
/sbin/route del $VIP &> /dev/null
#echo 0 > /proc/sys/net/ipv4/conf/$DEV/arp_filter
#echo 0 > /proc/sys/net/ipv4/conf/all/arp_filter
echo 0 > /proc/sys/net/ipv4/conf/$DEV/arp_ignore
echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 0 > /proc/sys/net/ipv4/conf/$DEV/arp_announce
echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce
echo "lvs dr model real server is stop..."
;;
status)
isthere=`/sbin/ifconfig $DEV:0 | grep $VIP`
isrothere=`netstat -rn | grep "$DEV" | grep $VIP`
if [ ! "$isthere" -o ! "$isrothere" ]; then
echo "lvs dr model real server is stopped..."
else
echo "lvs dr model real server is running..."
fi
;;
*)
echo "$0: usage:$0 {start|status|stop}"
exit 1
;;
esac
[/php]
开启真实服务器:
./lvsDrRs.sh start(如果不想当真实的服务器, ./lvsDrRs.sh stop即可)
二: 真实服务器信息(系统负载, cpu Idle, swap)的收集;
1: 在192.168.2.51和192.168.2.52上收集负载, cpu idle, swap的信息, shell脚本如下:
[php]
#!/bin/bash
#chkconfig: 2345 80 90
#Program:
# cat PM load, cpu idle, swap free per;
#History:
#2013/06/09 zhuanzitou first release
#
#ref:
# http://huangrs.blog.51cto.com/2677571/788668
getAverageLoad()#前十五分钟负载信息的收集
{
cpu_num=`grep -c 'model name' /proc/cpuinfo`
load_15=`uptime | awk '{print $NF}'`
average_load=`echo "scale=2;a=$load_15/$cpu_num;if(length(a)==scale(a)) print 0; print a" | bc`
echo "$average_load"
}
getCpuIdle()#cpu Idle信息的收集
{
cpu_idle=`top -b -n 1 | grep Cpu | awk '{print $5}' | cut -f 1 -d "."`
echo "$cpu_idle"
}
getSwapFree()# swap的利用率的收集;
{
swap_total=`free -m | grep Swap | awk '{print $2}'`
swap_free=`free -m | grep Swap | awk '{print $4}'`
swap_per=`echo "scale=2;a=$swap_free/$swap_total;if(length(a)==scale(a)) print 0; print a" | bc`
echo "$swap_per"
}
sendMessage()#把收集的信息回馈给调度器, 注意, 这里要配置ssh无须密码登录远程主机. 52的机器把ip改成52.
{
IP=51
scp /tmp/averageLoad zhuanzitou@192.168.2.49:/tmp/averageLoad${IP}
scp /tmp/cpuIdle zhuanzitou@192.168.2.49:/tmp/cpuIdle${IP}
scp /tmp/swapFree zhuanzitou@192.168.2.49:/tmp/swapFree${IP}
}
while true
do
averageLoad=`getAverageLoad`
echo $averageLoad > /tmp/averageLoad
cpuIdle=`getCpuIdle`
echo $cpuIdle > /tmp/cpuIdle
swapFree=`getSwapFree`
echo $swapFree > /tmp/swapFree
sendMessage
sleep 5
done
exit 0
[/php]
2: 把定期收集的信息在开机的时候就运行.
vim /etc/rc.local加入
nohup /root/loadCat.sh > /dev/null 2> /dev/null &
#nohup表示放到系统后台完成, &表示让程序在后台运行.
三: 把真实服务器的信息反馈给调度器;
1; 先配置ssh无须密码登录, 参考本人写的一篇博客, 里面有介绍配置ssh无须密码登录;
2; 在定期收集信息的时候, 同时把信息反馈给调度器;
四: 使用keepalived的MISC_CHECK自己编写脚本来实现动态负载均衡;
1; 把真实服务器反馈回来的信息进行收集整理, 并根据信息来决定服务器是否要运行. 脚本如下:
[php]
#!/bin/bash
#Program
# test host 192.168.2.51 lvs test;
#History:
#2013/06/11 zhuanzitou first release
#收集52的时候, 把所有的51改为52.
IP=51
averageLoad51=`cat /tmp/averageLoad51`
cpuIdle51=`cat /tmp/cpuIdle51`
swapFree51=`cat /tmp/swapFree51`
httpEnable51=`nc -v -z -w 2 192.168.2.51 80`
#因为shell不能比较浮点数, 因此使用bc工具来比较;
if [ "$httpEnable51" != "" ] && [ `echo "$averageLoad51 <= 0.7" | bc` -ne 0 ] && [ `echo "$cpuIdle51 >= 20" | bc` -ne 0 ] && [ `echo "$swapFree51 >= 0.2" | bc` -ne 0 ];then
exit 0
else
exit 1
fi
[/php]
2; 上面信息的解释:
当每颗cpu核的负载超过0.7, 或者cpuIdle值小于20%, 或者swap的利用率超过20%, 就把真实的服务器移除负载均衡的群集中.
五: 测试方法;
1: 使用ab压力测试;
ab -n 1000000 -c 100 http://192.168.2.149/
2: 查看真实服务器负载的变化;
3; 让真实服务器的负载超过0.7, 调度器就会自动把真实的服务器移除群集;
ipvsadm -ln查看调度器与真实服务器的信息;
4; 停止压力测试, 等负载恢复到0.7以下, 真实的服务器加入群集;
作者: 砖子头
日期: 2013/06/11
版本: 第一版