反向代理之HAProxy的简单应用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了反向代理之HAProxy的简单应用相关的知识,希望对你有一定的参考价值。

HAProxy:

      HAProxy是一款基于tcp和http的反向代理服务器,既能做7层(http)代理,也能做四层(tcp)代理,做四层代理时需要模拟实现,并且依然是基于socket通信,不支持正向代理,不提供缓存,但负载均衡能力强大,以及强大的负载均衡调度算法,特别适用于那些负载较大的web站点,对后端主机提供高可用。      

     HAProyx实现了一种事件驱动,单一进程模型,此模型支持非常大的、并发连接数。多进程或多线程模式受内存限制,系统调度器限制以及无处不在的锁限制,很少能处理数千并发连接。服务器如果只有两核cpu,HAProxy依然能提供高并发能力。

     HAProxy的缺点:在多核系统上,这些程序通常扩展性较差,必须进行优化以使每个CPU时间片做更多的工作。 

   

  HAProxy的特性:   

        1、单进程、事件驱动模型显著降低了上下文切换的开销及内存占用

        2、事件检查器允许其在高并发连接中对任何连接的任何事件实现即时探测

        3、在任何可用的情况下,单缓冲机制能以不复制任何数据的方式完成读写操作,这会节约大量的CPU时钟周期及内存带宽

        4、MRU内存分配器在固定大小的内存池中可实现即时内存分配,这能够显著减少创建一个会话的时长

        5、使用弹性二叉树进行存储,实现了以O(log(N))的低开销来保持计时命令、保持运行队列命令及管理轮询及最少连接队列

        6、优化HTTP首部分析,避免了在HTTP首部分析过程中重读任何内存区域

        7、精心的降低了昂贵的系统调用(产生软中断),大部分工作都在用户空间完成,如时间读取、缓冲聚合及文件描述符的启用和禁用等。

    

     HAProxy提供负载均衡的架构图:

     技术分享      


一、安装HAProxy

]# yum -y install haproxy    
]# rpm -ql haproxy
/etc/haproxy
/etc/haproxy/haproxy.cfg           //haproxy的配置文件
/etc/logrotate.d/haproxy           
/etc/sysconfig/haproxy             //额外的配置文件
/usr/bin/halog
/usr/bin/iprange
/usr/lib/systemd/system/haproxy.service    //启动程序

配置文件:

]# cat /etc/haproxy/haproxy.cfg
global                                        //全局配置
    log         127.0.0.1 local2           //定义全局日志,需要在/etc/rsyslog.conf中定义     
    chroot      /var/lib/haproxy           //禁锢功能,haproxy安全                           pidfile     /var/run/haproxy.pid       //pid文件
    maxconn     4000                       //设定单个haproxy进程所能接收的最大并发连接数
    user        haproxy                    
    group       haproxy
    daemon                                 //以守护进程运行
    nbproc 2                              //指明要启动的haproxy进程数量;默认只启动1个
    ulimit-n 20480                        //每个haproxy进程所能够打开的最大文件数,默认HAP                                            roxy自动调整
    maxpipes 1000                        //haproxy使用pipe机制实现内核级tcp报文重组;每进                                           程所能够使用的最大pipe数量;默认为maxconn/4
    #tune.bufsize:                       //缓冲区大小,默认设置
    #tune.chksize:                      //检查缓冲区大小,默认设置,建议不设置

代理相关的配置:

1、defaults:                      用于为listen/frontend/backend提供默认值

defaults                               
    mode                    http          //基于7层代理
    log                     global
    option                  httplog       //日志类别,采用httplog
    option                  dontlognull
    option http-server-close                //长连接时如果没数据传输,服务器自动关闭连接
    option forwardfor       except 127.0.0.0/8    //把发往backend server的请求报文中添加 “X-Forward-For”首部,其值为客户端主机地址,除了本机
    option                  redispatch      //当serverid对应的服务器挂掉后,强制定向到其 他健康服务器
    retries                 3               //3次连接失败就认为服务器不可用,主要通过后面的check检查
    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           //代理时所能接受的最大并发连接数,应该要比后端                                             主机的并发总和要小
    stats hide-version                     //隐藏统计页面的HAproxy版本信息



2、frontend <name>:   定义监听的套接字,用于接收客户端请求并与之建立连接  

frontend  main *:5000
    acl url_static       path_beg       -i /static /images /javascript /stylesheets
    acl url_static       path_end       -i .jpg .gif .png .css .js

    use_backend static          if url_static
    default_backend             app

<name>:前端名称,可以是数字,字母,下划线,-,:,.

bind:指明监听的套接字,可以直接在<name>跟监听的端口,也可以bind监听

bind *:80,*:443 
bind 10.0.0.1:10080,10.0.0.1:10443

acl:访问控制或补全访问列表

acl <aclname> <criterion> [flags][operator]<value>..

aclname:访问控制名称,区分大小写
critertion:匹配的标准  
       -i:不区分大小写
       -m: 匹配字符串
flags:标志位  
operator:操作比较符
value:需要匹配到的值

匹配的标准:7层捕获
1、path     : exact string match      //基于请求的路径匹配
   path_beg : prefix match            //匹配开头的字符
   path_dir : subdir match            //匹配目录
   path_dom : domain match            //匹配
   path_end : suffix match            //匹配给定路径结尾的字符
   path_len : length match            //匹配长度
   path_reg : regex match             //基于正则表达式匹配 
   path_sub : substring match         //substring匹配 
   
2、url     : exact string match       //基于请求的URL匹配
   url_beg : prefix match
   url_dir : subdir match
   url_dom : domain match 
   url_end : suffix match
   url_len : length match
   url_reg : regex match
   url_sub : substring match
   
http://www.mageud.com/admin/index.html 
url:   http://www.mageud.com/admin/index.html  
path:  /admin/index.html
 
 四层捕获:
   dst ip              //目标地址ip
   dst_port PORT       //目标地址端口 
   src ip              //源地址IP
   src_port PORT       //源地址端口
 
use_backend <backend> [{if | unless} <condition>]      //调用指定的后端主机   
default_backend <backend>                              //调用指定的默认后端主机

3、 backend <name>: 定义后端服务器组,类似于upstream,用于处理由frontend转发来的用户请求   

backend static
    balance     roundrobin
    server      static 127.0.0.1:4331 check

name:定义后端服务器组的名称

balance:指明调度算法

balance <algorithm> [<arguments>]

algorithm:调度算法,分为两类,动态算法和静态算法
    动态算法:权重可动态调整,支持慢启动,最大支持4095个后端主机
    静态算法:调整权重不会实时生效,需要重启,不支持慢启动,后端主机无限制
    
roundrobin: 轮询,动态算法,每个后端主机最多支持4128个连接;
static-rr: 轮询,静态算法,每个后端主机支持的数量无上限;
leastconn: 最少连接算法,根据后端主机的负载数量进行调度;仅适用长连接的会话
first: 根据服务器在列表中的位置,自上而下进行调度;前面服务连接数达到上限,新请求将调度到下一台服务器。

source: 源地址hash ;
   hash的计算方式:  hash-type <method> <function> <modifier>
   map-based:取模法;静态算法;
   consistent:一致性哈希法;动态算法;

   uri:对URI的左半部分或整个URI做hash计算,并由服务器的总权重相除后派发至某挑选出的后端主机,作用在于能够将对同一个URI的请求始终发往同一个backend server。适用于后端为缓存服务器的场景
  hash的计算方式:  hash-type <method> <function> <modifier>
   map-based:取模法;静态算法;
   consistent:一致性哈希法;动态算法;  
 
uri_params:对用户请求的uri中的<params>中的参数的值作hash计算,并由服务器的总权重相除后派发至某挑选出的后端主机。以确保同一用户的请求始终发往同一个backend server;
    hash的计算方式:  hash-type <method> <function> <modifier>
       map-based:取模法;静态算法;
       consistent:一致性哈希法;动态算法;
 
hdr(<name>):对于每个http请求,此处<name>指定的http首部会被取出;此首部如果没有有效值,
则轮询调度;否则,对其值作hash计算, 并由服务器的总权重相除后派发至某挑选出的后端主机,针对多个虚拟主机。
     hdr(Cookie),hdr(Host),hdr(User_Agent)

server: 指明后端服务器及参数

<name>:服务器的内部名称,出现在日志及警告信息中;如果设定了http-send-server-name,它还将被添加至发往此服务器的请求首部当中
<address>:服务器的地址,支持使用主机名
[:[port]]:端口映射:省略时,表示与bind的端口相同
[param*]:参数;
     backup: 设定当前server为备用服务器,仅在所有服务器均不可用时,方才启用:
     check:对后端服务器做健康状态检测;无check时表示假设后端主机始终可用,同时可使用辅助参数有很多;
     addr:通过此地址进行健康状态检测
     prot<port>: 通过此端口进行健康状态检测
     inter<delay>:连续两次检测之间的时间间隔,默认为2000ms
     falt<count>:连续多少的失败检测将标记服务器为dead,默认为2次
     rise<count>: 连续多少的成功检测将标记服务器为可用,默认为2次 
     cookie<value>:为当前server指定cookie值,用于实现基于cookie会话粘性
     disable:禁用此服务器
     maxconn<maxconn>:当前服务器支持的最大并发连接数;超出此值的连接将放置于请求队列中
     maxqueue<maxqueue>:当前服务器的队列上限
     redir<prefix>:将发往此服务器的所有的GET和HEAD请求重定向至指定的地址     
	 示例:server srv1 192.168.1.1:80 redir http://www.magedu.com check 
     weight<weight>:权重

定义基于http协议7层健康状态检测功能,默认是四层健康状态检测  

option httpchk 

option httpchk <uri>

option httpchk <method> <uri>

option httpchk <method> <uri> <version>

 backend https_relay
 mode tcp
 option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www
 server apache1 172.18.250.76:443 check port 80


mode{tcp|http|health}: 定义实例的工作模式;

tcp:当代理的为ssl,ssh,mysql等非http协议时使用,默认为此模式

http: 仅当代理的为http协议时使用

health: 工作健康状态检查响应模式,当收到请求仅回应”OK“时即断开连接

    注意:代理https时,要使用tcp模式


  cookie: 启用cookie会话粘性,面向后端主机

    用法:cookie <name>[rewrite]| insert | prefix ] [ indirect ] [ nocache ] [ postonly ] [ preserve ] [ httponly ] [ secure ] [ domain <domain> ]* [ maxidle <idle> ] [ maxlife <life> ]<font color="#ff0000"></font>

 <name>:

 rewrite:重写

 insert: 插入

 prefix: 添加前缀

cookie WEBSRV insert indirect nocache
server ser1 172.18.250.76:80 check cookie webser1
server ser2 172.18.250.78:80 check cookie webser2

技术分享

 listen <name>: 通过关联“前端“和”后端“定义一个完整的proxy server;

1、开启stats页面,提供管理统计Web页:

stats enable:      启用统计页;基于默认参数启用统计页;
 -stats uri:/haproxy?stats              //都是默认,可以不配置
 -stats realm :"HAProxy Statistics"
 -stats auth : no authentication
 -stats scope: no restriction
stats uri<prefix>:  定义统计页的访问uri前缀,通常要跟上?stats
stats realm<realm>: 设定认证时使用realm;
stats auth<user>:<passwd>  设定认证时使用的账号密码;可以使用多次
stats refresh <number>: 刷新时长
stats hide-version: 隐藏版本信息
stats admin {if | unless}<cond>:在指定的条件下启用admin功能

配置:
listen stats
    bind  *:9000
    stats enable          
    stats uri /                       //定义统计页的URI,不走默认配置
    stats realm Haproxy\ Statics  
    stats auth  admin:admin        
    stats admin if TRUE              //开启管理页面功能

技术分享

如果需要走7层检测则需要在backend中加入加入option httpchk

技术分享

listen也可以定义前端和后端,实现负载均衡

listen webserver *:80
    balance    roundrobin
    log  global
    option httpchk
    server ser1 172.18.250.76:80 check cookie webser1
    server ser2 172.18.250.78:80 check cookie webser2

技术分享  

技术分享



配置一个负载均衡器,实现动静分离

frontend webserver
     bind *:80
     acl php_page path_end -i .php
     use_backend phpserver if  php_page
     default_backend webser

backend phpserver
      balance roundrobin
      option httpchk
      cookie PHP insert indirect nocache          //基于cookie粘性实现会话保持
      server php1 172.18.250.75:80 check cookie phpsrv1  maxconn 100
      server php2 172.18.250.74:80 check cookie phpsrv2  maxconn 100

backend webser
      balance roundrobin
      option httpchk
      server web1 172.18.250.76:80 check weight 1 maxconn 10000
      server web2 172.18.250.78:80 check weight 2 maxconn 10000

测试静态页面:

技术分享

技术分享

测试动态页面:
技术分享


安装PHP应用,实现动静分离:

]# unzip Discuz_X3.2_SC_UTF8.zip       //四台服务器都安装论坛程序
]# yum -y install mysql-server php-mysql   //两台php安装mysql

技术分享

根据安装步骤,装完Discuz论坛:
技术分享安装完成,测试没问题


以上是关于反向代理之HAProxy的简单应用的主要内容,如果未能解决你的问题,请参考以下文章

反向代理负载均衡系列之Haproxy

反向代理负载均衡之haproxy

LB_之HAProxy 反向代理;代理mysql;高可用

http反向代理及haproxy

haproxy负载均衡器及反向代理

反向代理软件之HAproxy基础