lvs+keepalived+shell动态负载均衡的思路与实现

82cfe7db948216fe956c668855dfef9c

本博客的最终目标的讲解:    

由于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

版本: 第一版

转自 http://my.oschina.net/u/271856/blog/137111

还没有评论,快来抢沙发!

发表评论

  • 😉
  • 😐
  • 😡
  • 😈
  • 🙂
  • 😯
  • 🙁
  • 🙄
  • 😛
  • 😳
  • 😮
  • emoji-mrgree
  • 😆
  • 💡
  • 😀
  • 👿
  • 😥
  • 😎
  • ➡
  • 😕
  • ❓
  • ❗
  • 67 queries in 0.531 seconds