Haproxy负载均衡

一、Haproxy 简介
      Haproxy特别适用于那些负载特大的Web站点,这些站点通常又需要会话保持或七层处理。Haproxy+keepalived 高性能Web 运行千万级并发网站。
     HAProxy实现的是一种事件驱动、单一进程的架构模型,此类模型的优点在于能够支撑高并发大规模的连接。反之,多进程或多线程模型受内存和系统调度器的限制以及无处不在的锁限制,很难应对数以万计的高并发连接。HAProxy支持连接拒绝,通过拒绝连接,可以限制某些非法或有意的攻击型连接,从而降低其对网站带来的危害。的这一功能已成为目前应对小型DDOS攻击的主要方法之一,并且其他负载均衡器很难做到这点。此外, HAProxy还支持全透明代理,即可以将客户端地址或者任何指定地址直接连接到后端服务器,通过全透明代理,可以不用修改某些特殊服务器地址而使其直接接收并处理部分特定流量。
  HAProxy主要为基于 HTTP和TCP访问的应用服务提供负载均衡,如基于 Internet的连接服务和基于 web的应用服务。通过负载均衡算法,HAproxy能够接受数以万计的访问请求并将其转发到后端服务器池中进行处理,而后端服务器池就如一个强大的虚拟服务器接受 HAProxy转发的请求并进行处理。HAproxy的请求调度器(Scheduler)决定了后端服务器中每个服务器接受和处理的请求量,在没有权重的调度算法下,调度器为每台服务器分配相同数量的请求,而在加权调度算法下,调度器根据每台服务器的权重为每个后端服务器分配不同数量的请求。HAProxy允许用户自定义多个代理,并为每个代理提供负载均衡服务,代理由一个前端和一个或多个后端构成,前端定义了代理监听的IP地址(Virtual IP)和端口,同时还需在前端定义中关联与其相关的后端,而在HAProxy中,后端主要用于定义服务器池和负载均衡算法。HAProxy的负载均衡服务在7层,即应用层,在很多情况下,由于商业应用连续性的要求,管理员通常需要部署HAProxy,从而为基于HTTP的应用提供负载均衡和高可用性。
Haproxy 高性能负载均衡优点:
 • Haproxy 是支持虚拟主机的,可以工作在4、7层;
 • 能够补充Nginx 的一些缺点,比如Session 的保持、Cookie 的引导等工作;
 • 支持url 检测后端的服务器;
 • 它跟LVS 一样,只是一款负载均衡软件,单纯从效率上来讲,Haproxy更会比Nginx 有更出色的负载均衡速度,在并发处理上也是优于Nginx。
 • Haproxy 可以对MySQL读进行负载均衡,对后端的MySQL节点进行检测和负载均衡,Haproxy 支持多种算法。
 
二、HAProxy 安装
1、YUM
# yum install haproxy-y
2、源码安装
# cd /usr/src
# wget http://www.haproxy.org/download/1.8/src/haproxy-1.8.14.tar.gz
# tar zxvfhaproxy-1.8.14.tar.gz
# cd haproxy-1.8.14
# make TARGET=linux26PREFIX=/usr/local/haproxy/
# make installPREFIX=/usr/local/haproxy
# mkdir /etc/haproxy
# cp examples/auth.cfg/etc/haproxy/haproxy.cfg
# cpexamples/haproxy.init /etc/init.d/haproxy
# chmod +x/etc/init.d/haproxy
# ln -s/usr/local/sbin/haproxy /usr/sbin/
# mkdir/usr/share/haproxy
# /etc/init.d/haproxystart
 
三、Haproxy配置文件详解
Haproxy配置中分成五部分内容,当然这些组件不是必选的,可以根据需要选择作为配置。
 •global:参数是进程级的,通常和操作系统(OS)相关。这些参数一般只设置一次,如果配置无误,就不需要再次配置进行修改;
 •default:配置默认参数的,这些参数可以被利用配置到frontend,backend,listen组件;
 •frontend:接收请求的前端虚拟节点,Frontend可以根据规则直接指定具体使用后端的backend(可动态选择);
 •backend:后端服务集群的配置,是真实的服务器,一个Backend对应一个或者多个实体服务器;
 • listen:Frontend和Backend的组合体。
# vim/etc/haproxy/haproxy.cfg
#vim/etc/haproxy/haproxy.cfg
# this config needshaproxy-1.1.28 or haproxy-1.2.1
global
log127.0.0.1   local0                 #日志输出配置,所有日志都记录在本机,通过local0输出
log127.0.0.1   local1 notice
#log loghost    local0 info
ulimit-n82000                      #设置每个进程的可用的最大文件描述符
maxconn4096                       #最大连接数
chroot/var/lib/haproxy          #改变当前工作目录。
user     haproxy                      #所属用户的uid
group  haproxy                      #所属运行的gid
daemon                                 #以后台形式运行haproxy
nbproc3                                #启动3个ha-proxy实例
pidfile/var/run/haproxy.pid            #pid文件位置
debug                               #调试模式,输出启动信息到标准输出
#quiet                            #安静模式,启动时无输出
statssocket /var/lib/haproxy/stats #用户访问统计数据的接口
defaults
 log global
 log   127.0.0.1   local3              #日志文件的输出定向
 mode   http                        #默认的模式mode{ tcp|http|health },tcp是4层,http是7层,health只会返回OK
 option httplog                        #日志类别,采用httplog
 option httpclose                    #每次请求完毕后主动关闭http通道,ha-proxy不支持keep-alive,只能模拟这种模式的实现
 option dontlognull                #保证HAProxy不记录上级负载均衡发送过来的用于检测状态没有数据的心跳包
 option forwardfor                #如果后端服务器需要获得客户端真实ip需要配置的参数,可以从HttpHeader中获得客户端ip
 option  redispatch                #当serverId对应的服务器挂掉后,强制定向到其他健康的服务器
 option abortonclose                #当服务器负载很高的时候,自动结束掉当前队列处理比较久的链接
 retries 2                              #三次连接失败就认为是服务器不可用
 maxconn 3000                           #默认的最大连接数
#timeout http-keep-alive10s        #定义保持连接的超时时长
#timeout queue1m                #等待最大时长
 timeout http-request10s        #在客户端建立连接但不请求数据时,关闭客户端连接
 timeout connect10s                #连接超时
 timeout client1m                    #客户端超时
 timeout server1m                #服务器超时
 timeout check10s                #心跳检测超时
 #stats refresh 30s                        #统计页面自动刷新时间
 #stats uri /stats                          #统计页面url
 #stats realm Haproxy Manager         #统计页面密码框上提示文本
 #stats auth admin:password            #统计页面用户名和密码设置
 #stats hide-version                          #隐藏统计页面上HAProxy的版本信息
frontend www                #定义一个名为www的前端部分
bind*:80                #这里建议使用bind*:80的方式,要不然做集群高可用的时候有问题,vip切换到其他机器就不能访问了。
modehttp                #定义为HTTP模式
logglobal                #继承global中log的定义
optionforwardfor        #启用X-Forwarded-For,在requests头部插入客户端IP发送给后端的server,使后端server获取到客户端的真实IP
aclstatic_down nbsrv(static_server) lt 1# 定义一个名叫static_down的acl,当backendstatic_sever中存活机器数小于1时会被匹配到
aclphp_web url_reg -i /*.php$
或者#aclphp_web path_end -i .php                #定义一个名叫php_web的acl,当请求的url末尾是以.php结尾的,将会被匹配到
aclstatic_web url_reg -i /*.(css|jpg|png|jpeg|js|gif)$
或者#aclstatic_web path_end -i  .gif .png .jpg.css .js.jpeg        #定义一个名叫static_web的acl,当请求的url末尾是以.css、.jpg、.png、.jpeg、.js、.gif结尾的,将会被匹配到
use_backendphp_server ifstatic_down        #如果满足策略static_down时,就将请求交予backendphp_server
use_backendphp_server ifphp_web        #如果满足策略php_web时,就将请求交予backendphp_server
use_backendstatic_server ifstatic_web        #如果满足策略static_web时,就将请求交予backendstatic_server
default_backend            server                #默认后端
backend php_server                #定义一个名为php_server的后端部分
modehttp                #设置为http模式
balancesource                #设置haproxy的调度算法为源地址hash
cookieSERVERID        #允许向cookie插入SERVERID,每台服务器的SERVERID可在下面使用cookie关键字定义
optionhttpchk GET/test/index.php        #开启对后端服务器的健康检测,通过GET/test/index.php来判断后端服务器的健康情况
serverphp_server_1 192.168.28.134:80 cookie 1 check inter 2000 rise 3 fall 3 weight 2
serverphp_server_2 192.168.28.135:80 cookie 2 check inter 2000 rise 3 fall 3 weight 1
serverphp_server_bak 192.168.28.136:80 cookie 3 check inter 1500 rise 3 fall 3 backup
# server语法:server[:port] [param*]
#使用server关键字来设置后端服务器;为后端服务器所设置的内部名称[php_server_1],该名称将会呈现在日志或警报中、后端服务器的IP地址,支持端口映射[10.12.25.68:80]、指定该服务器的SERVERID为1[cookie1]、接受健康监测[check]、监测的间隔时长,单位毫秒[inter 2000]、监测正常多少次后被认为后端服务器是可用的[rise3]、监测失败多少次后被认为后端服务器是不可用的[fall 3]、分发的权重[weight 2]、最为备份用的后端服务器,当正常的服务器全部都宕机后,才会启用备份服务器[backup]
backendstatic_server                #定义一个名为static_server的后端部分
modehttp                #设置为http模式
optionhttpchk GET/test/index.html        #开启对后端服务器的健康检测,通过GET/test/index.html来判断后端服务器的健康情况
serverstatic_server_1 192.168.28.133:80 cookie 3 check inter 2000 rise 3 fall 3
backend server                    #定义的默认后端
    balance    roundrobin        #轮询
    server app1 127.0.0.1:5001 check
    server app2 127.0.0.1:5002 check
    server app3 127.0.0.1:5003 check
    server app4 127.0.0.1:5004 check
 
四、HAProxy监控页面
   HAProxy为每个监听代理提供了实时监控,并可以将监控参数以GUI页而的形式呈现给用户。要使用HAProxy的GUI页面,需要在/etc/haproxy/haproxy.cfg配置文件中配置相应的监听参数,通常需要配置一个Listen置段(也可以是Frontend或 Backend配置段),即可通过 HTTP协议访问HAProxy的监控页面,最为常用的HAProxy监控页面配置如下:
listenstatus                                        #定义一个名为status的部分,也可以放在frontend或backend段中
modehttp                               #使用协议
bind0.0.0.0:8888                        #监听地址与端口
logglobal                                #继承global中log的定义
#log127.0.0.1 local3err                        #错误的日志记录
statsenable                      #启用信息统计功能
#optionhttplog                        #采用http日志格式
statsrefresh 10s                        #统计页面自动刷新时间
statsuri /stats                                #统计页面url
statsrealm Haproxy Manager                #统计页面密码框上提示文本
statsauthadmin:password                #统计页面用户名和密码设置
#statshide-version                        #隐藏统计页面上HAProxy的版本信息
常用的HAProxy监控后端服务器状态配置如下:
listenserver_status                                #定义一个名为server_status的部分,也可以放在frontend或backend段中
modehttp                               #使用协议
bind0.0.0.0:1081                        #监听地址与端口
logglobal                                #继承global中log的定义
#log127.0.0.1 local3err                        #错误的日志记录
monitor-uri/server_status                #网站健康检测URL,用来检测网站是否可用,正常返回200,不正常返回503
aclserver_dead nbsrv(server_web) lt2        #定义网站down时的策略在负载均衡上的指定backend的有效机器小于1台时返回true
monitorfail ifserver_dead                #当满足策略的时候返回503
monitor-net192.168.28.149/32                #来至此IP的日志信息不会被记录和转发
monitor-net192.168.28.150/32                #来至此IP的日志信息不会被记录和转发
    HAProxy的监控页面将每项资源的监控参数以表格形式呈现给用户,并将监控参划分为七个类别,即 Queue、Sessionrate、Sessions、Bytes、Denied、Errors、 Warning、server,每组参数类别下又有多个详细参数,其中各个参数的解释如下。
(1)Queue
  cur:表示当前队列的请求数量。
  Max:表是当前队列最大的请求数量。
  Limit:表示队列的限制数量。
(2) Session rate
  Cur:每秒会话连接数量。
  Max:每秒会话数量最大值。囗Limit:每秒会话数量的限制值。
(3) Sessions
  Total:总共会话数量。
  Cur:当前的会话数量。
  Max:最大会话数量。
  Limit:会话连接限制。
  Lbtot:选中一台服务器所用的总时间。
  Last:最后一次会话时间。
(4) Bytes
  In:网络会话输人字节数总量。
  Out:网络会话输出字节数总量。
(5) Denied
  Req:被拒绝的会话请求数量。
  Resp:拒绝回应的请求数量。
(6) Errors
  Req:错误的请求数量。
  Conn:错误连接数量。
  Resp:错误响应数量。
(7) Warnings
   Retr:重新尝试连接的请求数量。
   Redis:重新发送的请求数量。
(8) Server
  status:后端服务器状态,可以有UP和 DOWN两种状状态。
  LastChk:持续检查后端服务器的时间。
  Wght:服务器权重。
  Act:活动后端服务器数量。
  Bck:后端备份服务器的数量。
  Down:状态为Down的后端服务器数量。
  Downtime:服务器总的Downtime时间。
  Throttle:状态 Backup变为Active的服务器数量。
 
五、HAProxy 配置参考
 • FrontEnd配置段参考:
FrontEnd配置段主要通过bind配置监听的虚拟IP地址和端口,同时Frontend配置里面可以定义多个acl以进行请求精确匹配,Frontend配置段中还可以定义与全局默认配置段重名的参数以覆盖全局配置段的参数。
frontendweb_server   #定义前端名称,可自定义。
bind0.0.0.0:80          #监听IP地址与端口
modehttp         #使用http协议
logglobal         #应用全局的日志配置
optionhttplog         #启用http的log
optionhttpclose         #每次请求完主动关闭http通道
optionforwardfor        #允许发往服务器的请求头部中插入“X-ForwardedFor”头部
aclwww_server hdr_dom(host) -i www.xxx.com        #如果请求的域名满足www.xxx.com则返回true,-i表示忽略大小写
aclwww_server2 hdr_reg(host) -i ^(xx.xx.com|xx.xx.com)    #请求的域名满足正则表达式中的2个域名返回true -i 表示忽略大小写
aclwww_server3 url_sub -i killall=        #在请求的url中包含killall=,则此控制策略返回true,否则为false
aclwww_server4 url_dir -iallow                #在请求的url中存在allow作为部分地址路径,则此控制策略返回true,否则为false
aclwww_server5 hdr_cnt(Content-length) eq0        #当请求的header中Content-length等于0时返回true
blockifwww_server2                #当请求中header中Content-length等于0时阻止请求返回403
blockif !www_server3 ||www_server4        #block表示阻止请求,返回403错误,当前表示如果不满足策略3,或者满足策略4,则阻止请求
use_backendserver ifwww_server        #如果满足策略www_server时,就将请求交予backendserver
。。。。。。
 
 • BackEnd配置段参考:
Backend配置段主要配置负载均衡算法,定义后端服务器以及相应的健康检查方式等参数,同时Backend配置段也可以定义与默认全局配置段重名的参数,从而覆盖全局参数值以进行局部后端定义。
backend server                         #后端名称
modehttp                   #http七层模式
balanceroundrobin            #负载均衡的方式
optionignore-persist {if | unless} <condition>  #在某些条件下拒绝持续连接,适用于静态文件的负载均衡。
optionindependant-streams           #启用双向超时处理,如socket的read和write
optionlog-health-checks            #记录健康检查日志
optionlog—separate—errors           #对非完全成功的连接改变日志记录等级
optionlogasap            #传输大文件时可以提前记录日志
optionmysql-check           #mysql健康检查
option  persist            #强制将http请求发往已经down掉的server
optionredispatch          #是否允许重新分配在session失败后
optionsmtpchk           #smtp检查
optionhttpchk           #通过http协议进行健康检查
optionsocket-stats         #允许对单个socket进行统计
option  srvtcpka            #是否允许向server发送 keepalive
optiontcpka             #是否允许向 server和 client发送keepalive
optiontcplog            #允许记录tcp连接的状态和时间
optiontransparent            #允许客户端透明代理
optionhttpchk GET /check.html HTTP/1.1   #心跳检测的文件
tick-tabletype ip size 1024            #为当前后端配置粘性表;表存储条目类型为IP地址,允许存储1k大小的IP地址
stickon dst               #定义一个请求模式dst,以将一个客户端同某个后端服务器关联起来
timeoutserver 90m            #后端服务器最大等待时间,超过此时间则认为服务器不可用。
server server_1192.168.28.134:80 check inter 1500 rise 3 fall 3 weight 1 port 9800 backupon-marked-down shutdown-sessions
server server_2192.168.28.135:80 check inter 1500 rise 3 fall 3 weight 1 port 9800 backupon-marked-down shutdown-sessions
server server_3192.168.28.136:80 check inter 1500 rise 3 fall 3 weight 1 port 9800 backupon-marked-down shutdown-sessions
注:
如上进行多后端服务器定义, checkinter 1500是检测心跳频率, rise 3表示3次检查结果正确则认为服务器可用,fall 3表示检测结果失败3次则认为服务器不可用,weight代表服务器权重。port 9800表示通过端口9800来进行基于 http的健康检查, backup表示该服务器是备份服务器,只有在其他非backup服务器均不可用的情况下负载均衡器才会使用该后端服务器,默认情况下使用第一个标记为 backup的后端服务器, upon-marked-downshutdown-sessions表示当该服务器被认为是 shutdown的时候,关闭全部与该服务器的请求连接。
 
六、配置Haproxy + keepalived
 • Haproxy + keepalived master端keepalived.conf配置文件如下:
! Configuration Filefor keepalived
global_defs {
   notification_email {
      ytwu@leqee.com
   }
   notification_email_from ytwu@leqee.com
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
   vrrp_skip_check_adv_addr
#   vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}
vrrp_scriptcheck_haproxy {
script"/data/sh/check_haproxy.sh"
interval2
weight2
}
#VP1
vrrp_instance VI_1 {
    state MASTER
    interface ens33
    lvs_sync_daemon_inteface ens33
    virtual_router_id 51
    priority 110
    advert_int 1
    nopreempt
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.28.88/24
    }
    track_script {
check_haproxy
}        
}
 • Haproxy + keepalived backup端keepalived.conf配置文件如下:
    state BACKUP
    priority 90
##其他配置同MASTER端。
 • 创建check_haproxy 脚本:
#!/bin/bash
#auto check haproxyprocess
killall -0 haproxy
if [[ $? -ne 0 ]];then
systemctlstop keepalived
fi