一、HAProxy  

    HAProxy提供高可用性、负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。


    HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。HAProxy运行在当前的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整合进当前的架构中, 同时可以保护web服务器不被暴露到网络上。


    HAProxy实现了一种事件驱动, 单一进程模型,此模型支持非常大的并发连接数。多进程或多线程模型受内存限制 、系统调度器限制以及无处不在的锁限制,很少能处理数千并发连接。事件驱动模型因为在有更好的资源和时间管理的用户端(User-Space) 实现所有这些任务,所以没有这些问题。此模型的弊端是,在多核系统上,这些程序通常扩展性较差。这就是为什么他们必须进行优化以使每个CPU时间片(Cycle)做更多的工作。


    HAProxy支持从4层至7层的网络交换,即覆盖所有的TCP协议。就是说,Haproxy 甚至还支持 Mysql 的均衡负载。


    Nginx,ApacheProxy,lighttpd,Cheroke 等,带反向代理均衡负载的产品,都是 Web 服务器,但是他们自己能够提供静态(html,jpg,gif..)或动态(php,cgi..)文件的传输以及处理。

    但 HAProxy 仅仅,而且专门是一款的用于均衡负载的应用代理。其自身并不能提供http服务。 


    HAProxy拥有非常不错的服务器健康检查功能,还有专门的系统状态监控页面,当其代理的后端服务器出现故障, HAProxy会自动将该服务器摘除,故障恢复后再自动将该服务器加入。

wKiom1N6AaOxLaBaAADcPnspqkI156.jpg



二、HAProxy特点

  • 只专注负载均衡

  • 强大的服务器健康检查功能,支持自动添加与排除服务器

  • 自带强大的系统状态监控页面支持虚拟主机

  • 支持对Mysql读进行负载均衡,对后端的MySQL节点进行检测和负载均衡。(后端的MySQL slaves超过10台时性能不如LVS,此时建议LVS+Keepalived)

  • 比Nginx有更出色的负载均衡速度,并发处理上也优于Nginx

  • 支持全透明代理

  • 支持连接拒绝 

  • 支持会话保持和七层处理


三、HAProxy负载均衡调度算法

1.roundrobin :

  • 加权轮询;

  • 动态算法,这表示支持服务器活动时修改其权重,服务器下线后重新上线时支持慢启动;

  • 不过,每个后端服务器仅能最多接受4128个连接;

2.static-rr :

  • 加权轮询;

  • 静态,不支持服务器活动时修改,需要重启服务才能生效;

  • 后端服务器连接数上没有限制;

3.leastconn :

  • 最少连接者先处理,新的连接请求被派发至具有最少连接数目的后端服务器;

  • 动态,可以在运行时调整其权重,慢启动;(推荐较长时间会话服务,使用此算法)

4.source :

  • 同一个客户端IP的请求由同一服务器处理,实现session保持;

  • 默认为静态,支持使用hash-type调整为动态;

  • 实现方式为,源地址进行hash运算,并由后端服务器的权重总数相除后派发至相应的服务器,若权重总数发生变化,如服务器宕机或添加新服务器,可能调度至不同服务器,session将无法保持;常用于负载均衡无cookie功能的基于TCP的协议;

5.uri :

  • 同一个URI的请求由同一服务器处理;

  • 默认为静态算法,支持使用hash-type调整为动态;

  • 实现方式为,对URI的左半部分(“问题”标记之前的部分)或整个URI进行hash运算,并由服务器的总权重相除后派发至相应的服务器,若权重总数发生变化,可能调度至不同服务器;

  • 常用于代理缓存或反病毒代理以提高缓存的命中率;

6.url_param :

  • 确保同一个用户ID的请求将被送往同一个特定的服务器;

  • 默认为静态算法,支持使用hash-type调整为动态;受限于权重;

  • 若请求中没有出现指定的参数或没有有效值,则使用轮询;

7.hdr (<name>):

  • 通过<name>指定的HTTP首部将会被检索,根据HTTP请求头来锁定每一次HTTP请求;

  • 默认为静态方法, 先对<name>做hash计算然后 hash/weight计算,支持使用hash-type调整为动态;

  • 受限于权重;

  • 若相应的首部中没有出现指定的参数或没有有效值,则使用轮训;

8.rdp-cookie(name):

  • 表示根据cookie(name)来锁定并哈希每一次TCP请求,使同一个用户(或同一个会话ID)总是发送同一个特定的服务器

  • 默认为静态算法,支持使用hash-type调整为动态;受限于权重;

  • 如果没有cookie,则使用轮询;


四、HAProxy配置文件解析

  1. 配置文件格式

    HAProxy主要包括:

  • "global"段,全局配置参数,参数为进程级别的参数,且通常与其运行的OS相关。

  • proxy相关配置段,包括"defaults","listen","frontend","backend";

    "defaults"段用于为所有其它配置段提供默认参数,这配置默认配置参数可由下一个“defaults”所重新设定。

        "frontend"段用于定义一系列监听的套接字,这些套接字可接受客户端请求并与之建立连接。
        "backend"段用于定义一系列“后端”服务器,代理将会将对应客户端的请求转发至这些服务器。
        "listen"段通过关联“前端”和“后端”定义了一个完整的代理,通常只对TCP流量有用。


 2. 主配置文件 haproxy.cfg 解析

global  
    log         127.0.0.1 local2 
    chroot      /var/lib/haproxy     #修改haproxy的工作目录至指定的目录并在放弃权限之前执行chroot()操作,
                                   #可以提升haproxy的安全级别,要确保指定的目录为空目录且任何用户均不能有写权限; 
    pidfile      /var/run/haproxy.pid #将所有进程的pid写入文件启动进程的用户必须有权限访问此文件。 
    maxconn    4000                #最大连接数,默认4000 
    user        haproxy             #用户 
    group       haproxy             #组 
    daemon                         #让haproxy以守护进程的方式工作于后台,其等同于haproxy命令“-D”选项的功能,
                                   #当然,也可以在命令行中以“-db”选项将其禁用; 
    # turn on stats unix socket  #unix socket 文件
    stats socket /var/lib/haproxy/stats
#--------------------------------------------------------------------- 
# common defaults that all the 'listen' and 'backend' sections will  
# use if not designated in their block  
#默认的全局设置,这些参数可以被利用配置到frontend,backend,listen段 
#---------------------------------------------------------------------  
defaults
    mode                   http   #默认的模式mode { tcp|http|health },tcp是4层,http是7层,health只会返回OK 
    log                     global  #采用全局定义的日志 
    option                  httplog #日志类别http日志格式
    option                  dontlognull #不记录健康检查的日志信息
    option http-server-close             #当客户端超时时,允许服务器关闭连接
    option forwardfor        except 127.0.0.0/8  #在响应头部加入forwardfor,但不记录本机转发的日志 
    option                  redispatch  #在使用基于cookie的会话保持时,使用此项 
                                      #一旦后端某一server宕机时,能够将其会话
                                      #重新派发到其它的upstream server               
    retries                 3         #3次连接失败就认为服务不可用,也可以通过后面设置 
    timeout http-request    10s       #请求超时 
    timeout queue          1m       #队列超时 
    timeout connect         10s       #连接超时 
    timeout client           1m       #客户端连接超时 
    timeout server          1m       #服务器连接超时 
    timeout http-keep-alive  10s       #长连接超时 
    timeout check          10s      #检查超时 
    maxconn               3000     #最大并发连接数
#--------------------------------------------------------------------- 
# main frontend which proxys to the backends #frontend 与backends  代理配置 
#---------------------------------------------------------------------  
frontend  main *:5000
#acl策略配置
    acl url_static       path_beg       -i /static /p_w_picpaths /javascript /stylesheets 
    acl url_static       path_end       -i .jpg .gif .png .css .js
    use_backend static          if url_static  #满足策略要求,则响应策略定义的backend页面
    default_backend             app         #不满足则响应backend的默认页面
#--------------------------------------------------------------------- 
# static backend for serving up p_w_picpaths, stylesheets and such #定义使用静态文件 
#---------------------------------------------------------------------  
backend static            #后端静态服务器
    balance     roundrobin #负载均衡模式轮询 
    server      static 127.0.0.1:4331 check #服务器定义
#--------------------------------------------------------------------- 
# round robin balancing between the various backends  
#---------------------------------------------------------------------  
backend app              #非静态的文件服务器
    balance     roundrobin #负载均衡模式轮询 
    server  app1 127.0.0.1:5001 check #服务器定义,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动静分离的部署

  1. 拓扑结构

    node1:HAProxy(172.16.1.1)

    node2:static-server(httpd: 172.16.1.11)

    node3:dynamic-server(httpd: 172.16.1.12)

haproxy配置

global
    log         127.0.0.1 local2
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon
    # turn on stats unix socket
    stats socket /var/lib/haproxy/stats

defaults
    mode                    http    
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close   
    option forwardfor       except 127.0.0.0/8    
    option                  redispatch    
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 10000    #最大并发连接数

frontend  proxy *:80    #前端代理
    acl url_static       path_beg       -i /static /p_w_picpaths /javascript /stylesheets
    acl url_static       path_end       -i .html .jpg .gif .png .css .js
    acl dynamic_content  path_end       -i .php
    use_backend static          if url_static
    default_backend             dynamic
#---------------------------------------------------------------------
# static backend for serving up p_w_picpaths, stylesheets and such
#---------------------------------------------------------------------
backend static    #后端静态服务器
    balance     roundrobin
    server      web1  172.16.1.11:80 inter 3000 rise 2 fall 3 check maxconn 5000

backend dynamic    #后端动态服务器
    balance     roundrobin
    server      web2  172.16.1.12:80 inter 3000 rise 2 fall 3 check maxconn 5000

listen statistics
        mode http
        bind *:8080    #把stats页面绑定到8080端口
        stats enable   #开启stats功能
        stats auth hoo:hoo       #认证的用户名和密码
        stats uri /admin?stats    #指定uri访问路径
        stats realm   Haproxy\ Statistics  #定义显示文字 
        stats hide-version        #为了安全(版本bug),隐藏版本信息
        stats admin if TRUE      #如果认证通过了就允许管理
        stats refresh 5s          #页面5秒刷新一次
        acl allow src 172.16.0.0/16    #定义访问控制列表
        tcp-request content accept if allow
        tcp-request content reject

3. httpd配置

  a. node2 配置

# yum install httpd -y
# echo \<h1\>welcom to web1\<\/h1\> > /var/www/html/index.html
# service httpd start

  b. node3 配置

# yum install httpd -y
# vim /var/www/html/index.html
<h1>welcom to web2</h1>
<?php
    phpinfo();
?>
# service httpd start

4. 配置haproxy日志

    a.配置日志系统

# vim /etc/sysconfig/rsyslog# Options for rsyslogd
# Syslogd options are deprecated since rsyslog v3. 
# If you want to use them, switch to compatibility mode 2 by "-c 2" 
    #明显已有提示
# See rsyslogd(8) for more details 
SYSLOGD_OPTIONS="-c 2 -r"

    b.增加日志设备

# vim /etc/rsyslog.conf
#添一行
local2.*                       /var/log/haproxy.log

    c.重启日志服务

# service rsyslog restart

 5.启动服务

    node1

# haproxy -c -f /etc/haproxy/haproxy.cfg  //检查配置文件
# service haproxy start
# netstat -tunlp | grep :80

 6.测试服务

   a.在web1(172.16.1.11)的网页目录下,随意放一张图pic.jpg

   b.请求172.16.1.1/pic.jpg

        图片显示

   c.请求172.16.1.1

        显示phpinfo()函数信息

   d.haproxy统计页面输出

    请求:172.16.1.1:8080/admin?status

    输入帐号,密码即可访问


五、简单的基于HAProxy的MySQL服务的负载均衡

    与http服务多大区别,只需改变mode合port,同时根据业务不同调整时间和连接数。

配置文件:

global 
    log         127.0.0.1 local2
    chroot      /var/lib/haproxy
    pidfile      /var/run/haproxy.pid 
    maxconn     4000 
    user        haproxy 
    group       haproxy 
    daemon
defaults
    mode                    tcp 
                #基于四层
    log                     global 
    option                  httplog 
    option                  dontlognull 
    retries                 3 
    timeout http-request    10s 
    timeout queue           1m 
    timeout connect         10s 
    timeout client          1m 
    timeout server          1m 
    timeout http-keep-alive 10s 
    timeout check           10s 
    maxconn                 600
listen statistics
    mode http 
    bind *:1080 
    stats enable
    stats hide-version 
    stats uri     /admin?stats 
    stats realm   Haproxy\ Statistics 
    stats auth    hoo:hoo 
    stats admin if TRUE
    
frontend mysqlproxy 
    bind *:3306 
    mode tcp 
    log global 
    default_backend mysqlservers
    
backend mysqlservers
    balance leastconn 
    server dbser1 172.16.1.11:3306 check port 3306 intval 2 rise 1 fall 2 maxconn 300 
    server dbser2 172.168.1.12:3306 check port 3306 intval 2 rise 1 fall 2 maxconn 300