六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 518|回复: 0

HAProxy双机高可用方案之HAProxy+Keepalived

[复制链接]
 楼主| 发表于 2016-2-2 13:30:35 | 显示全部楼层 |阅读模式
HAProxy双机高可用方案之HAProxy+Keepalived
由于公司的注册用户已超过八百万了,而且每天都有持续增涨的趋势,而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,我们给它执行权限,脚本内容如下所示:
  1.     #!/bin/sh  
  2.     # chkconfig 35 on  
  3.     # description: HAProxy is a TCP/HTTP reverse proxy which is particularly suited for high availability environments.  
  4.      
  5.     # Source function library.  
  6.     if [ -f /etc/init.d/functions ]; then  
  7.       . /etc/init.d/functions  
  8.     elif [ -f /etc/rc.d/init.d/functions ] ; then  
  9.       . /etc/rc.d/init.d/functions  
  10.     else  
  11.       exit 0  
  12.     fi  
  13.      
  14.     # Source networking configuration.  
  15.     . /etc/sysconfig/network  
  16.      
  17.     # Check that networking is up.  
  18.     [ ${NETWORKING} = "no" ] && exit 0  
  19.      
  20.     [ -f /usr/local/haproxy/conf/haproxy.cfg ] || exit 1  
  21.      
  22.     RETVAL=0
  23.      
  24.     start() {  
  25.       /usr/local/haproxy/sbin/haproxy -c -q -f /usr/local/haproxy/conf/haproxy.cfg  
  26.       if [ $? -ne 0 ]; then  
  27.         echo "Errors found in configuration file."  
  28.         return 1  
  29.       fi  
  30.      
  31.       echo -n "Starting HAproxy: "  
  32.       daemon /usr/local/haproxy/sbin/haproxy -D -f /usr/local/haproxy/conf/haproxy.cfg -p /var/run/haproxy.pid  
  33.       RETVAL=$?  
  34.       echo  
  35.       [ $RETVAL -eq 0 ] && touch /var/lock/subsys/haproxy  
  36.       return $RETVAL  
  37.     }  
  38.      
  39.     stop() {  
  40.       echo -n "Shutting down HAproxy: "  
  41.       killproc haproxy -USR1  
  42.       RETVAL=$?  
  43.       echo  
  44.       [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/haproxy  
  45.       [ $RETVAL -eq 0 ] && rm -f /var/run/haproxy.pid  
  46.       return $RETVAL  
  47.     }  
  48.      
  49.     restart() {  
  50.       /usr/local/haproxy/sbin/haproxy -c -q -f /usr/local/haproxy/conf/haproxy.cfg  
  51.       if [ $? -ne 0 ]; then  
  52.         echo "Errors found in configuration file, check it with 'haproxy check'."  
  53.         return 1  
  54.       fi  
  55.       stop  
  56.       start  
  57.     }  
  58.      
  59.     check() {  
  60.       /usr/local/haproxy/sbin/haproxy -c -q -V -f /usr/local/haproxy/conf/haproxy.cfg  
  61.     }  
  62.      
  63.     rhstatus() {  
  64.       status haproxy  
  65.     }  
  66.      
  67.     condrestart() {  
  68.       [ -e /var/lock/subsys/haproxy ] && restart || :  
  69.     }  
  70.      
  71.     # See how we were called.  
  72.     case "$1" in  
  73.       start)  
  74.         start  
  75.         ;;  
  76.       stop)  
  77.         stop  
  78.         ;;  
  79.       restart)  
  80.         restart  
  81.         ;;  
  82.       reload)  
  83.         restart  
  84.         ;;  
  85.       condrestart)  
  86.         condrestart  
  87.         ;;  
  88.       status)  
  89.         rhstatus  
  90.      ;;  
  91.       check)  
  92.         check  
  93.         ;;  
  94.       *)  
  95.         echo $"Usage: haproxy {start|stop|restart|reload|condrestart|status|check}"  
  96.         RETVAL=1
  97.     esac  
  98.      
  99.     exit $RETVAL
复制代码
(2)/usr/local/haproxy/conf/haproxy.cfg文件的内容如下所示(两台HAProxy机器的配置内容一样):
  1.     global  
  2.             log 127.0.0.1   local0  
  3.             maxconn 65535  
  4.             chroot /usr/local/haproxy  
  5.             uid 99   
  6.             gid 99  
  7.             daemon  
  8.             nbproc 8  
  9.             pidfile /usr/local/haproxy/haproxy.pid  
  10.             debug  
  11.      
  12.     defaults   
  13.              log     127.0.0.1       local3   
  14.              mode   http   
  15.              option httplog   
  16.              option httpclose   
  17.              option dontlognull   
  18.              option forwardfor   
  19.              option redispatch   
  20.              retries 2   
  21.              maxconn 2000   
  22.              stats   uri     /haproxy-stats   
  23.              contimeout      5000   
  24.              clitimeout      50000   
  25.              srvtimeout      50000   
  26.      
  27.     frontend www.1paituan.com  
  28.              bind *:80  
  29.              mode http   
  30.              option httplog  
  31.              log global   
  32.              default_backend phppool   
  33.      
  34.     backend phppool  
  35.             balance source   
  36.             option httpchk HEAD /index.jsp HTTP/1.0  
  37.             server web1  203.93.236.147:80 weight 5  check inter 2000 rise 2 fall 3   
  38.          server  web2  203.93.236.146:80 weight 3  check inter 2000 rise 2 fall 3
复制代码
配置文件建议写成这种frontend(前台)和backend(后台)的形式,方便我们根据需求也可以利用HAProxy的正则做成动静分离或根据特定的文件名后缀(比如.php或.jsp)访问指定的phppool池或javapool池(Nginx也能实现此项功能),我们还可以指定静态服务器池,让客户端对静态文件(比如bmp或jsp或html)访问我们的Nginx静态服务器,所以前后台的模型也是非常有用的,不喜欢frontend(前台)和backend(后台)的朋友可以对比下以前没有采用这种模式的配置文件,内容如下:
  1.     global  
  2.             log 127.0.0.1   local0  
  3.             maxconn 65535  
  4.             chroot /usr/local/haproxy  
  5.             uid 99  
  6.             gid 99  
  7.             daemon  
  8.             nbproc 8  
  9.             pidfile /usr/local/haproxy/haproxy.pid  
  10.             debug  
  11.      
  12.     defaults  
  13.              log     127.0.0.1       local3  
  14.              mode   http  
  15.              option httplog  
  16.              option httpclose  
  17.              option dontlognull  
  18.              option forwardfor  
  19.              option redispatch  
  20.              retries 2  
  21.              maxconn 2000  
  22.              balance source  
  23.              stats   uri     /haproxy-stats  
  24.              contimeout      5000  
  25.              clitimeout      50000  
  26.              srvtimeout      50000  
  27.      
  28.     listen  www.1paituan.com  
  29.             bind *:80  
  30.             mode http  
  31.             option httplog  
  32.             log global  
  33.             option httpchk HEAD /index.jsp HTTP/1.0  
  34.             server web1  203.93.236.147:80 weight 5  check inter 2000 rise 2 fall 3  
  35.             server web2  203.93.236.146:80 weight 3  check inter 2000 rise 2 fall 3
复制代码
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用法的朋友建议熟悉下)。
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 restart4.验证此架构及注意事项
我们可以关闭主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集群和高可用版版主。

http://network.51cto.com/art/201110/295955_2.htm


HAProxy双机高可用方案之HAProxy+Keepalived

该会员没有填写今日想说内容.
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表