由于公司的注册用户已超过八百万了,而且每天都有持续增涨的趋势,而PV/日已经有向千万靠扰的趋势;原有的Web架构越来越满足不了我们的需求了,所以我们也考虑上能抗高并发的HAProxy来作为我们网站的最前端的负载均衡器;因为我已经在东莞的二个项目上面成功实施了HAProxy+Keepalived双机方案,所以我在这里也尝试在公司的网站上这种负载均衡高可用架构,即HAProxy+Keepalived。
HAProxy+Keepalived配置过程如下:
1. 做好整个环境的准备工作。
两台服务器DELL 2950均要做好准备工作,比如设置好hosts文件及进行ntpd对时。
网络拓朴很简单,如下所示:
ha1.cn7789.com eth0:203.93.236.145
ha2.cn7789.com eth0:203.93.236.142
网卡用其自带的千兆网卡均可。
硬盘模式没有要求,Raid0或Raid1均可。
网站对外的VIP地址是:203.93.236.149,这是通过Keepalived来实现的,原理请参考前面的章节;同时这也是我们的网站的外网DNS对应的IP。
2. HAProxy和Keepalived的安装过程
关于此安装过程,请大家参考前面的内容,这里就不重复了,我们主要是注意关键位置的改动:
(1)首先是要建立HAProxy启动、重启、关闭等状态脚本,我这里的HAProxy脚本为/root/haproxy,我们给它执行权限,脚本内容如下所示:
#!/bin/sh #chkconfig35on #description:HAProxyisaTCP/HTTPreverseproxywhichisparticularlysuitedforhighavailabilityenvironments. #Sourcefunctionlibrary. if[-f/etc/init.d/functions];then ./etc/init.d/functions elif[-f/etc/rc.d/init.d/functions];then ./etc/rc.d/init.d/functions else exit0 fi #Sourcenetworkingconfiguration. ./etc/sysconfig/network #Checkthatnetworkingisup. [${NETWORKING}="no"]&&exit0 [-f/usr/local/haproxy/conf/haproxy.cfg]||exit1 RETVAL=0 start(){ /usr/local/haproxy/sbin/haproxy-c-q-f/usr/local/haproxy/conf/haproxy.cfg if[$?-ne0];then echo"Errorsfoundinconfigurationfile." return1 fi echo-n"StartingHAproxy:" daemon/usr/local/haproxy/sbin/haproxy-D-f/usr/local/haproxy/conf/haproxy.cfg-p/var/run/haproxy.pid RETVAL=$? echo [$RETVAL-eq0]&&touch/var/lock/subsys/haproxy return$RETVAL } stop(){ echo-n"ShuttingdownHAproxy:" killprochaproxy-USR1 RETVAL=$? echo [$RETVAL-eq0]&&rm-f/var/lock/subsys/haproxy [$RETVAL-eq0]&&rm-f/var/run/haproxy.pid return$RETVAL } restart(){ /usr/local/haproxy/sbin/haproxy-c-q-f/usr/local/haproxy/conf/haproxy.cfg if[$?-ne0];then echo"Errorsfoundinconfigurationfile,checkitwith'haproxycheck'." return1 fi stop start } check(){ /usr/local/haproxy/sbin/haproxy-c-q-V-f/usr/local/haproxy/conf/haproxy.cfg } rhstatus(){ statushaproxy } condrestart(){ [-e/var/lock/subsys/haproxy]&&restart||: } #Seehowwewerecalled. case"$1"in start) start ;; stop) stop ;; restart) restart ;; reload) restart ;; condrestart) condrestart ;; status) rhstatus ;; check) check ;; *) echo$"Usage:haproxy{start|stop|restart|reload|condrestart|status|check}" RETVAL=1 esac exit$RETVAL
#p#
(2)/usr/local/haproxy/conf/haproxy.cfg文件的内容如下所示(两台HAProxy机器的配置内容一样):
global log127.0.0.1local0 maxconn65535 chroot/usr/local/haproxy uid99 gid99 daemon nbproc8 pidfile/usr/local/haproxy/haproxy.pid debug defaults log127.0.0.1local3 modehttp optionhttplog optionhttpclose optiondontlognull optionforwardfor optionredispatch retries2 maxconn2000 statsuri/haproxy-stats contimeout5000 clitimeout50000 srvtimeout50000 frontendwww.1paituan.com bind*:80 modehttp optionhttplog logglobal default_backendphppool backendphppool balancesource optionhttpchkHEAD/index.jspHTTP/1.0 serverweb1203.93.236.147:80weight5checkinter2000rise2fall3 serverweb2203.93.236.146:80weight3checkinter2000rise2fall3
配置文件建议写成这种frontend(前台)和backend(后台)的形式,方便我们根据需求也可以利用HAProxy的正则做成动静分离或根据特定的文件名后缀(比如.php或.jsp)访问指定的phppool池或javapool池(Nginx也能实现此项功能),我们还可以指定静态服务器池,让客户端对静态文件(比如bmp或jsp或html)访问我们的Nginx静态服务器,所以前后台的模型也是非常有用的,不喜欢frontend(前台)和backend(后台)的朋友可以对比下以前没有采用这种模式的配置文件,内容如下:
global log127.0.0.1local0 maxconn65535 chroot/usr/local/haproxy uid99 gid99 daemon nbproc8 pidfile/usr/local/haproxy/haproxy.pid debug defaults log127.0.0.1local3 modehttp optionhttplog optionhttpclose optiondontlognull optionforwardfor optionredispatch retries2 maxconn2000 balancesource statsuri/haproxy-stats contimeout5000 clitimeout50000 srvtimeout50000 listenwww.1paituan.com bind*:80 modehttp optionhttplog logglobal optionhttpchkHEAD/index.jspHTTP/1.0 serverweb1203.93.236.147:80weight5checkinter2000rise2fall3 serverweb2203.93.236.146:80weight3checkinter2000rise2fall3
HAProxy的正则功能虽然没Nginx强大灵活,但也是非常有用的;大家可以参考下面的文档来熟悉下HAProxy的正则写法,这些对于我们以后的工作帮助还是很大的,内容如下:
####################acl策略定义######################### #如果请求的域名满足正则表达式返回true -i是忽略大小写 acl denali_policy hdr_reg(host) -i ^(www.gemini.taobao.net|my.gemini.taobao.net|auction1.gemini.taobao.net)$ #如果请求域名满足trade.gemini.taobao.net 返回 true -i是忽略大小写 acl tm_policy hdr_dom(host) -i trade.gemini.taobao.net #在请求url中包含sip_apiname=,则此控制策略返回true,否则为false acl invalid_req url_sub -i sip_apiname= #在请求url中存在timetask作为部分地址路径,则此控制策略返回true,否则返回false acl timetask_req url_dir -i timetask #当请求的header中Content-length等于0时返回 true acl missing_cl hdr_cnt(Content-length) eq 0 ######################acl策略匹配相应################### #当请求中header中Content-length等于0 阻止请求返回403 block if missing_cl #block表示阻止请求,返回403错误,当前表示如果不满足策略invalid_req,或者满足策略timetask_req,则阻止请求。 block if !invalid_req || timetask_req #当满足denali_policy的策略时使用denali_server的backend use_backend denali_server if denali_policy #当满足tm_policy的策略时使用tm_server的backend use_backend tm_server if tm_policy #reqisetbe关键字定义,根据定义的关键字选择backend reqisetbe ^Host:\ img dynamic reqisetbe ^[^\ ]*\ /(img|css)/ dynamic reqisetbe ^[^\ ]*\ /admin/stats stats #以上都不满足的时候使用默认mms_server的backend default_backend mms_server Keepalived的配置过程比较简单,这里略过,大家可以参考我们前面的配置,配置成功后我们可以分别在二台机器上启动HAProxy及Keepalived服务(建议在Screen模式下开启HAProxy服务,不熟悉Sreen用法的朋友建议熟悉下)。 |
#p#
3.替HAProxy添加日志支持
我们编辑/etc/syslog.conf文件, 添加内容如下:
local3.* /var/log/haproxy.log local0.* /var/log/haproxy.log
我们编辑/etc/sysconfig/syslog文件,修改内容如下:
SYSLOGD_OPTIONS="-r -m 0"
然后重启syslog服务,命令如下:
service syslog restart
4.验证此架构及注意事项
我们可以关闭主HAProxy机器或重新启动,看在此过程中,VIP地址有没有正确的转移到从HAProxy机器上,影响我们访问网站没,以上步骤我自己测试过多次,而且线上环境的稳定运行,证明HAProxy+Keeaplived双机方案确实是有效的。
关于HAProxy+Heartbeat这种负载均衡高可用架构,有些情况我也跟大家说明一下:
◆在此HAProxy+Keepalivp负载均衡高可用架构中,我们是如何解决session的问题呢?我们这里采用的是它自身的balance source机制,它跟Nginx的ip_hash机制原理类似,是让客户机访问时始终访问后端的某一台真实的web服务器,这样让session就固定下来了;
◆option httpchk HEAD /index.jsp HTTP/1.0 是网页监控,如果HAProxy检测不到Web的根目录下没有index.jsp,就会产生503报错。
◆有网友配置HAProxy时喜欢用listen 203.93.236.141:80这样的格式,这样其实不好,做负载均衡高可用时由于从机分配不到VIP地址,会导致从机启动不了,我建议用bind *:80的方式代替。
◆HAProxy的并发监控暂时没有Nginx中的相关模块,但可以考虑用SHELL命令或自行开发PHP或JSP程序来监控。
5.HAProxy的监控页面
我们可以在地址栏输入http://www.1paituan.com/haproxy-stats/,显示界面如下(HAProxy自带的监控页面,也是我非常喜欢的功能之一):
作者介绍:
余洪春(抚琴煮酒·微博),《构建高可用Linux服务器》一书作者,一拍网系统架构师、资深项目管理工程师,ChinaUnix集群和高可用版版主。
转载请注明:IT运维空间 » 运维技术 » HAProxy双机高可用方案之HAProxy+Keepalived
发表评论