HAProxy是一个开源的、高性能的、基于TCP(第四层)和HTTP(第七层)应用的负载均衡软件,借助HAProxy可以快速、可靠地提供基于TCP和HTTP应用的负载均衡解决方案。
显著优点:
可靠性和稳定性非常好,可以与硬件级的F5负载均衡设备相媲美;
最高可以同时维护40 000~50 000个并发连接,单位时间处理的最大请求数为20 000个,最大数据处理能力可达10Gbps
支持多于8种负载均衡算法,同时也支持session(会话)保持。
支持虚拟主机功能,这样实现web负载均衡更加灵活
支持(HAProxy1.3版本之后)连接拒绝、全透明代理等功能,这些是其他负载均衡器所不具备的
拥有一个功能强大的服务器状态监控页面,通过此页面可以实时了解系统的运行状况
拥有功能强大的ACL支持,能给使用带来很大方便
我们这里采用源码包的安装方法:
http://haproxy.1wt.eu(官方网址)
安装方法这里不做介绍,重点是是服务启动的方法:
源码包安装方式是没有启动脚本的,是能通过命令的方式进行启动和关闭,什么都不会输出,只能通过netstat 的方式进行验证,很是麻烦
HAProxy安装完成后,会在根目录的sbin目录下生成一个可执行的二进制文件haproxy,对HAProxy的启动,关闭,重启等维护操作都是通过它来实现的,执行“haproxy -h ”即可得到此文件的用法:
Haproxy [-f <配置文件>] [-vdVD] [-n 最大并发连接总数] [-N 默认的连接数]
我们习惯使用service xxx start|restart|stop|status的方式,于是有了下面的脚本的编写:
示例1:
########################################
#!/bin/bash
#chkconfig: 2345 85 15
#description:HAProxy load balancer
DAEMON=haproxy
PROG_DIR=/usr/local/haproxy
RETVAL=0
success() { #这个函数的是为了动态的显示“.”,借助了python,使得语句简洁,优美
ma=`python <<eof
print 5*" ."
eof
`
for j in $ma
do
sleep 0.2
echo -n "$j"
done
}
start() {
PROG_STAT=$(netstat -antpu | grep ${DAEMON})
if [ -z "$PROG_STAT" ];then
haproxy -f $PROG_DIR/conf/haproxy.cfg
sta=$(netstat -antpu | grep ${DAEMON})
if [ -z "$PROG_STAT" ];then
echo -ne "Service is starting\t\t" && success && echo -en "\e[32m[OK!!]\e[0m" && echo
fi
else
echo "Service is already started!"
RETVAL=65
fi
}
stop() {
PROG_STAT=$(netstat -antpu | grep ${DAEMON})
if [ -z "$PROG_STAT" ];then
echo "Service is already stoped!"
else
kill -9 $(cat $PROG_DIR/run/${DAEMON}.pid)
PROG_STAT=$(netstat -antpu | grep ${DAEMON})
if [ -z "$PROG_STAT" ];then
echo -ne "Service is stoping\t\t" && success && echo -en "\e[32m[OK!!]\e[0m" && echo
RETVAL=66
fi
fi
}
restart() {
haproxy -f $PROG_DIR/conf/haproxy.cfg -st `pidof ${DAEMON}`
PROG_STAT=$(netstat -antpu | grep ${DAEMON})
if [ -n "$PROG_STAT" ];then
echo -ne "Service is restarting\t\t" && success && echo -en "\e[32m[OK!!]\e[0m" && echo
fi
}
status() {
PROG_STAT=$(netstat -antpu | grep ${DAEMON})
if [ -z "$PROG_STAT" ];then
echo "Service is stoped!!"
else
echo "Service is running......"
fi
}
case $1 in
"start") #每个变量内容建议用“”括起来
start
;;
"stop")
stop
;;
"restart")
restart
;;
"status")
status
;;
*) # *代表所有其他值,不要加“”
echo "Usage: /etc/init.d/${DAEMON} {start|stop|restart|staus} "
;;
esac
exit $RETVAL
===========================================
示例2:(更加精简,有效)
########################################
#!/bin/bash
#
# chkconfig: 2345 85 15
# descrition: haproxy loadbalancer
DAEMON=haproxy
PROG_DIR=/usr/local/haproxy
RETVAL=0
success() { #跟朋友的探讨,使用shell本身来实现;当然也可以使用for的遍历循环,
总之方法有很多种
for ((i=0;i<=5;i++))
do
sleep 0.2
echo -n "."
done
}
start ()
{
PROG_STAT=$(netstat -tlnp | grep ${DAEMON})
if [ -z "$PROG_STAT" ]; then
$PROG_DIR/sbin/$DAEMON -f $PROG_DIR/conf/${DAEMON}.cfg
echo -ne "Starting ${DAEMON}......\t\t\t" && success
echo -e "\e[32m[OK]\e[0m"
else
echo "$DAEMON is already running"
RETVAL=65
fi
}
stop ()
{
PROG_STAT=$(netstat -tlnp | grep ${DAEMON})
if [ -n "$PROG_STAT" ]; then
echo -ne "stopping ${DAEMON}......\t\t\t" && success
PROG_PID=$(cat $PROG_DIR/run/${DAEMON}.pid)
kill $PROG_PID
echo -e "\e[32m[OK]\e[0m"
else
echo "$DAEMON is already stopped"
RETVAL=66
fi
}
restart()
{
echo -ne "restarting ${DAEMON}......\t\t\t" && success
PROG_PID=$(cat $PROG_DIR/run/${DAEMON}.pid)
$PROG_DIR/sbin/$DAEMON -f $PROG_DIR/conf/${DAEMON}.cfg -st $PROG_PID
echo -e "\e[32m[OK]\e[0m"
}
status ()
{
PROG_STAT=$(netstat -tlnp | grep ${DAEMON})
if [ -z "$PROG_STAT" ]; then
echo "${DAEMON} stopped"
else
echo "${DAEMON} running"
fi
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
status)
status
;;
*)
echo "Usage /etc/init.d/$DAEMON {start | stop | restart | status}"
RETVAL=67
esac
exit $RETVAL
===================================
cp haproxy /etc/init.d/
chkconfig --add haproxy
chkconfig --list haproxy
service haproxy start|restart|stop|status
经过反复测试,相当好用!
小结:
1) 在编写一个脚本时,最好将基本结构搭建起来,将之后的心思放在内容的实现之上
2) 在调用python功能时,报错信息很重要,英语的重要性可见一斑;(我这里提示"indent"
(缩进)的异常)
3) 实现了基本功能,剩下的就是功能的完善,示例1和示例2的最大差别就是逻辑的前后之差,导致代码结构明显改变