haproxy反代负载均衡

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了haproxy反代负载均衡相关的知识,希望对你有一定的参考价值。

haproxy是用于实现作为后端反代以实现负载均衡器。

实现负载均衡有多种方案:可在tcp层即四层和应用层即七层实现负载均衡:

四层:lvs也是工作在四层的;

七层:nginx、ats等多种软件工具;


haproxy域lvs相比,调度能力肯定是不如lvs,因为lvs工作在内核空间,与后端real server通信时,没有套接字数量和连接的限制,可以调度海量客户端的请求;而haproxy是工作在七层,毕竟基于套接字实现与real server通信的;但是,haproxy正因为基于七层,可以根据http协议中的首部的任何header进行调度,所以haproxy的调度粒度远远比lvs要精细的多。


在七层实现调度负载均衡器的除了haproxy,还有比较常用的nginx,二者其实不分伯仲,完全根据跟人喜欢择其一用之。只不过,它们的调度概念是相似的。与nginx所不同之处在于,nginx工作是master/worker模型,由多个worker负责响应处理用户请求,master只负责把用户请求接进来;而HAProxy的单一进程,一个进程可以处理数以万计的请求;


这也正是因为,nginx的worker中有一个锁机制,内部还有个负载均衡机制,当用户请求到达时,多个worker轮流的响应,如果不是由前端master调度的,判断worker中谁处理下一次请求,则谁持有了锁,谁才能接收请求的;所以只要是多进程模型必须有锁限制机制;因此,多进程模型会消耗大量内存空间,会受到前端主控进程的调度能力以及锁等资源的共同限制;而HAProxy是单一进程。


HAProxy性能特性:

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

2.事件检查器(event checker)允许其在高并发连接中对任何连接的任何事件实现即时探测;

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

4.MRU(最近最多使用)内存分配器在固定大小的内存池中可实现即时内存分配,这能够显著减少创建一个会话的时长;

5.树型存储:侧重于使用作者多年前开发的弹性二叉树,实现了以O(log(N))的低开销来保持计时器命令、保持运行队列命令及管理轮询及最少连接队列;

6.优化的HTTp首部分析:优化的首部分析功能避免了在http首部分析过程中重读任何内存区域;

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


软件特性:只是http协议的反向代理,不提供缓存功能,但额外支持对tcp层对基于tcp通信的应用做LB;

使用场景:适合用于大型互联网外网或者内网4&7层负载均衡;


衡量负载均衡器的关键指标:

可以从三个因素来评估负载均衡器的性能:

1.会话率;指定是会话创建、删除的能力,每秒钟可以创建新会话的数量;

2.会话并发能力;可以同时持有的会话数量;

3.数据处理速度


haproxy安装:

centos6.4+版本已经把haproxy软件包收录到base源中。

配置文件:/etc/haproxy/haproxy.cfg

环境配置文件:/etc/sysconfig/haproxy


]# yum -y install haproxy

]# rpm -ql haproxy 可查看相关文件存放路径


haproxy配置:大体分两部分

global:全局段,定义haproxy进程工作特性

    进程及安全配置相关的参数

    性能调整相关的参数

    Debug参数

proxies:代理段

    defaults:为代理提供默认设置;

    listen=frontend+backend

    frontend:定义前端

    backend:定义后端


defaults 默认代配置段

技术分享


可对比nginx作为反代负载均衡器时的配置结构:

upstream BACKEND_SERVER1 {

ip_hash;

server ...;

server ...;

}


upstream BACKEND_SERVER2 {

leastconn;

server ...;

server ...;

}


upstream fcgi {

server ...;

server ...;

}

server {

listen

location URI {

proxy_pass http://BACKEND_SERVER1;

}


location \.(php)$ {

fastcgi_pass fastcgi://fcgi;

}


}


server {

location URI {

proxy_pass http://BACKEND_SERVER2;

}

可见,其实与nginx的配置段功能完全相似,只不过表现方式略有不同而已。

haproxy中的linsten指令相当于nginx中的fastcgi_pass,专门反代后端固定的主机。

而haproxy中的frontend指令相当于nginx中的server指令,设置前端供客户端访问主机的各属性。

还有haproxy中的backend指令就相当于nginx中的upstream指令,设置后端主机的各属性。

最后,default是haproxy中设定默认设置的,如果在frontend、backend和listen中都没设置属性值,则它们将继承default中设定的值。


haproxy配置中有很多指令,但是指令是有使用位置的限制的,就是在不同的配置段中使用不同的相应指令。例如有些指令不能用在backend段,有些不能用在frontend,还有些指令不能用在default中。


使用listen设置简单的反代:

物理机使用win7系统,虚拟机使用centos7系统

haproxy反代服务器:172.18.11.111

后端主机:172.18.11.11

后端主机:172.18.11.12


在后端提供http服务,测试页面:

]# vim /var/www/html/index.html

<h1>RS1 172.18.11.11</h1>

]# vim /var/www/html/index.html

<h1>RS2 172.18.11.12</h1>


]# vim /etc/haproxy/haproxy.cfg

在backend app配置段,最后添加:


listen web *:80 #定义前端监听的服务名为web,端口80;

    balance roundrobin #调度算法为加权轮询

    server web-RS1 172.18.11.11:80 check #后端主机名自定义为web-RS1,check为进行健康状态检测;

    server web-RS2 172.18.11.12:80 check


listen stats *:9001 #添加了haproxy的状态页面,名称定义为stats,端口设为9001;

    stats enable #启用状态页面;

    stats uri /haproxyadmin?stats #此项指令,可以省略,为默认路径,建议修改;

    stats realm haproxy\ statistics #设置访问状态页时认证,提示信息,带空格要使用转义符;

    stats auth admin:pass #设定登录名admin,密码为pass;

    stats admin if TRUE #如果认证成功,开启页面管理接口;


浏览器测试:http://172.18.11.111/

多次刷新,交替显示:

RS1 172.18.11.11

RS2 172.18.11.12


设定访问状态页认证时,显示haproxy状态页:

技术分享


global配置参数:

log:定义全局的syslog服务器,最多可定义两个,用于实现将haproxy产生的日志发往此服务器予以存储;

maxconn <number>:设定单个haproxy进程所能接受的最大并发连接数;其等同于命令行选项-n;ulimit -n自动计算的结果正是参照此参数设定的;

其它选项,一般都不需要设定。


代理相关的参数:

分四段:

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

frontend <name>:定义监听的套接字(一个前端),可以有多个端口,用于接收客户端请求并与之建立连接;类似于nginx的server;

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

listen <name>:通过关联前端和后端,定义一个完整的proxy server;通常用在tcp流量上;


注意:所有代理都应该有名称


name:名字可使用大小写字母,数字,下划线(_),短横线(-),点号,冒号;

bind:指明监听的套接字;设定监听的ip和端口;用在frontend,listen,backend中;

    bind [<address>]:<port_range> [,...]

    bind /<path> [, ...] [param*]

其中,address和port不走过多解释了,就是设置ip地址和端口,<path>表示使用unix socket套接字文件,用于linux本机通信;


balance:设定调度方法,用在default,listen,backend中;

    balance <algorithm> [<arguments>]  使用指定的调度算法;

    balance url_param <param> [check_post [<max_wait>]] 指定基于url的参数做调度;


<algorithm>:调度算法

roundrobin:动态算法,(加权)轮询;

权重可动态调整动态生效;根据权重轮流使用每个服务器,支持权重的运行时调整及慢启动机制,最大支持4095个后端主机;默认权重为1;其它使用hash调度方式的都支持动静两种方式;动态算法指的是服务器权重,可以在运行时调整,以实现实例的慢启动;所以可以加新server进来,而且可定义权重且可动态调整,不会瞬间调度大量请求,时逐渐调度请求上来的;服务器权重不同时就是加权轮询,相同时就是轮询;


static-rr:静态加权轮询;

静态算法,不支持权重的运行时调整及慢启动机制;权重在服务器运行时改变了也不生效,除非重启服务器,而重启会导致此前所有连接断开,然后才重新调度的;但后端主机无数量上限;当服务器掉线时,健康状态检测又恢复上线时,立即加入服务器列表中取,且立即调度大量连接请求至此服务器,没有慢启动功能;而roundrobin则会慢慢调度请求至服务器;


leastconn:加权最少连接;动态算法;

后端具有最少连接数的服务器将接收到请求,根据后端服务器当前连接的活动个数少来调度;

haproxy一般推荐使用在较长时间会话场景中;例如,LDAP,mysql等协议;并不适用用短时间连接,不是特别适用指的是由于leastconn在计算调度权重时,还得扫描后端服务器当前会话数量,所以性能有影响,消耗cpu资源,但是带来的收益是很低的;

支持权重的动态改变,支持慢启动,属于wlc调度算法;对于短时间的连接不超过5秒钟,或2秒,一般建议使用roundrobin算法;


first:

根据服务器在列表中的位置,自上而下进行调度;前面的服务器连接数达到上限时,才将新请求调度至下一个服务器;这种算法好处在于可省服务器;要保证单台服务器支撑多个连接时没有问题,性能还支撑一个没有什么区别时会很有用;

每一个后端主机要定义最大并发连接数上限;在定义最大连接数时可以定义在三个位置:全局的最大并发连接数上限、每个frontend或listen的最大并发连接数上限、后端主机最大并发连接数上限;


适用于会话较长的tcp连接;例如LDAP,MySQL等;


source:

相当于nginx的ip-hash或lvs的sh算法,原地址哈希hash,默认为取模法;静态调度;类似于uri算法,指不过是哈希的源ip,而不是uri;

将来自于同一个地址的请求,始终发往同一台后端主机;


取模法:将原地址哈希计算后除以服务器总权重最后取模;结果落在哪个节点上,就有哪个节点发往器响应;服务器总数发生变化,会话会全局失效,会影响全局调度效果;在分布式场景中是相当不靠谱,尤其后端是缓存服务器时;默认为静态的,但是可使用hash-type指令设定支持动态;


一致性哈希:服务器变得仅影响局部调度;动态调度;第一次调度时,基于取模法进行调度,一旦分配了服务器,后面再访问时将始终发往同一台服务器;通常用在tcp模式中;没有插入cookie时才会使用;如果协议支持cookie插入,就可以根据cookie进行调度,实现会话保持;


uri:基于uri做hash计算

先回顾下URL的完整格式,才能正确理解uri的调度算法;

URL的语法格式:

<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>

解释:

<scheme> 表示使用的协议

<user>:<password>@<host>:<port> 要求认证,指定用户名、密码、主机名或ip、端口

;<params> 分号隔开的是参数,传递给请求的参数;

例如:

ftp://downloads.magedu.com/pub/gnu;type=d

http://www.magedu.com/hammers;sale=false/index.html;graphics=true

?<query> 问号隔开的是查询串,指定向数据库发起查询条件;

http://www.joes-hardware.com/inventory-check.cgi?item=12731

查询数据库item为12731的项目,返回给inventory-check.cgi这个脚本,再由此脚本处理以后的结果返回给客户端;

#<frag> 片段,同一页面上的不同段落锚点;


再来看uri的调度算法:

url_param:基于url指定参数做hash计算

对用户请求的uri中的<params>中的参数的值做hash计算,并由服务器的总权重相除取模后派发至某挑选出的后端主机;此算法通常用于追踪请求中的用户标识,尤其是登录类的电商站点,以确保来自同一个用户的请求始终发往同一个后端服务器;支持动静两种方式,使用hash-type指定;


hdr(<name>):指定某一首部做hash计算

类似于nginx中的hash,可哈希请求报文中的任意首部,即可以基于任意首部做调度;

例如:

listen web

    bind *:80,*:8080

    balance hdr(Host)

    hash-type consistent

    server web-RS1 172.18.11.11:80 check weight 1

    server web-RS2 172.18.11.12:80 check weight 2


hash-type指令,指定对什么进行哈希计算:

hash-type <method> <function> <modifier>

其中:<method>包括map-based和consistent;

map-based:就是取模法;默认方法,是静态算法,不支持权重运行时调整及慢启动;

consistent:就是一致性哈希算法,动态算法,支持权重运行时调整及慢启动;


cookie <name> [ rewrite | insert | prefix ] [ indirect ] [ nocache ]

   [ postonly ] [ preserve ] [ httponly ] [ secure ]

   [ domain <domain> ]* [ maxidle <idle> ] [ maxlife <life> ]

启用基于cookie的持久连接功能;

注意,不是用来管理用户通信中的cookie,而是启用与后端服务器通信时持久连接功能;


server <name> <address>[:[port]] [param*]

定义后端主机中的服务器及其参数;


<name>:服务器的内部名称,仅在haproxy中使用;主要作用会出现在日志及警告信息中,可用来判断故障服务器,如果设定了http-send-server-name,它还将被添加至发往此服务器的请求首部当中;

<address>:服务器的ip地址,支持使用主机名;

[:[port]]:端口映射;省略时,表示与bind的端口相同;


[param*]:可选参数;

backup:设定为备用服务器,相当于sorry server;仅在所有服务器均不可用时,才启用;

check:对后端服务器做健康状态检测,无check时,表示假设后端主机始终可用,同时可使用辅助参数有很多;健康状态检测又三种:网络层检测、传输层检测(端口在未必服务正常,精确度不高)、应用层检测;

addr:通过此地址进行健康状态检测;

port <port>:通过此端口进行健康状态检测;

inter <delay>:连续两次检测之间的时间间隔,默认2000毫秒;每隔多长时间做一次健康检测;

fall <count>:连续多少次的失败检测将标记服务器检测为dead;默认3次;

rise <count>:连续多少次的成功检测将标记服务器为available;默认2次;

httpchk:基于http协议进行健康状态检测;是独立的参数进行设置;类似的还有"smtpchk", "mysql-check", "pgsql-check" and "ssl-hello-chk"分别用来定义7层检测的;


check-ssl:与后端通信使用ssl协议时此行用到;

disabled:表示禁用,类似于varnish中标记为down状态;

id <value>:为每个服务器设置一个持久ID,是基于id的会话粘性才会用到;

maxconn <maxconn>:当前服务器支持的最大并发连接数,超出此值的连接将被放置请求队列中;

maxqueue <maxqueue>:当前服务器的队列上限;

minconn <minconn>:如果设定了此参数,那么,最大值就成为动态的,可以根据后端服务器负载状态动态调整;


on-error <mode>:当判断后端服务器连续出现error时要做哪种模式;

<mode>:

fastinter:

fail-check:检测失败;

sudden-death:间歇性down;

mark-down:标记为down;

on-marked-down <action>:标记为down时,执行的动作;

on-marked-up <action>:标记为up时,执行的动作;

redir <prefix>:将发往此服务器的所有的GET和HEAD请求重定向至指定的地址;这个地址完全可以是haproxy代理没有关系的另外的主机;发送302响应码;

weight <weight>:服务器的权重;


maxconn <conn>:

定义实例的最大并发连接数;


标记后端主机为backup,例如:server web-RS1 172.18.11.11:80 check weight 1 backup

标记后端主机的最大连接数、队列长度,定义后端主机的的总最大连接数;例如:

maxconn 7700

server web-RS1 172.18.11.11:80 check weight 1 maxconn 2000 maxqueue 200

server web-RS2 172.18.11.12:80 check weight 2 maxconn 5000 maxqueue 500

注意:maxconn=所有后端server定义的maxconn之和+所有后端server定义的maxqueue之和;


option httpchk 默认检测主页响应码为200;

option httpchk <uri>

option httpchk <method> <uri>

option httpchk <method> <uri> <version>

定义基于http协议7层健康状态检测功能;

<uri>:如果没指明,默认检测主页;

<method>:检测为请求方法;

<version>:检测表示http协议的版本;默认为http 1.0;


mode { tcp|http|health }

定义实例的工作模式;

tcp(四)层:给代理的为ssl,ssh,mysql等非http协议时使用,默认即为此模式;如果服务主机是https主机,要使用mode tcp模式;因为haproxy代理分析不了请求报文首部,加密了;

http(七)层:仅当代理为http协议时使用;包括7层过滤器、内容交换;

health:工作于健康状态检测响应模式;当收到请求时仅回应OK后就断开连接;


设置haproxy反代,负载均衡非http协议,如监听ssl服务,例如:

listen sshserver

    bind *:20002

    balance leastconn

    mode tcp

    maxconn 20

    server sshserver1 172.18.11.11:22 check

    server sshserver2 172.18.11.12:22 check

注意:代理https时,要使用mode 指明tcp模式;


cookie <name> [ rewrite | insert | prefix ] [ indirect ] [ nocache ]

          [ postonly ] [ preserve ] [ httponly ] [ secure ]

          [ domain <domain> ]* [ maxidle <idle> ] [ maxlife <life> ]

cookie:基于cookie进行会话保持;

<name>:用于指明cookie中的某个名称,这个名称定义了那一段cookie信息是用来做会话粘性时被监控、修改、或者插入信息以实现持久性的;

rewrite:重写;整个cookie信息将会被haproxy重写,并在内部加上服务器id信息,当然,也有可能把某些信息依然放进去,只是把其中的某些项改了;相当于把insert和prefix结合使用;

insert:插入;在原有的cookie中插入;

prefix:添加前缀;把cookie信息插入在原有cookie信息的最左侧;

nocache:当使用insert操作时,当客户端经由一个代理连接haproxy主机时,推荐使用此选项;用来操作对应的cache标记来判定对应信息是否能够作为重写标准;

preserve:服务器可以保留某个指定的cookie标记,以实现基于此信息的转发;

secure:指示haproxy在insert时添加一个secure cookie标记;作用在于不允许后端服务器操作里面的cookie信息;

domain <domain>:对应的cookie对应在哪个域上;


基于cookie实现粘性,例如:

listen web

    log global

    bind *:80,*:8080

    balance roundrobin

    option httpchk

    maxconn 7700

    cookie web insert indirect nocache 

    server web-RS1 172.18.11.11:80 check weight 1 maxconn 2000 maxqueue 200 cookie rs1

    server web-RS2 172.18.11.12:80 check weight 2 maxconn 5000 maxqueue 500 cookie rs2


统计接口启用相关的参数:


stats enable:启用统计页;可以基于默认参数直接启用统计页;默认参数如下,其实,只需这一个指令即可,其它都有默认值;

默认设置:

stats uri   : /haproxy?stats

stats realm : "HAProxy Statistics"

stats auth  : no authentication

stats scope : no restriction


定义访问haproxy的状态页uri,例如:

listen stats *:9001

    stats enable

    stats uri /

    stats realm haproxy\ statistics

    stats auth admin:pass

    stats admin if TRUE

浏览器输入:http://172.18.11.111:9001/

技术分享

stats uri <prefix>:统计页的访问时的uri前缀,通常要跟上?stats;默认为/haproxy?stats;不建议使用默认公开的状态统计页uri;

stats realm <realm>:设定认证时使用realm,使用字符串中有空格时,要用转义符或加双引号;

stats auth <user>:<passwd>:认证时的账号和密码;可以使用多次;

stats refresh <delay>:统计页的自动刷新时间间隔;默认单位秒;

stats show-desc [ <desc> ]:设置显示状态页的描述信息;


例如:

listen stats *:9001

    stats enable

    stats uri /

    stats realm haproxy\ statistics

    stats auth admin:pass

    stats admin if TRUE

    stats refresh 3s

    stats show-desc magedu test haproxy

技术分享

stats hide-version:在统计页隐藏版本信息;

stats admin { if | unless } <cond>:在指定的条件下acl满足时,启用admin功能;


option forwardfor [ except <network> ] [ header <name> ] [ if-none ]

把发往backend server的请求报文中添加X-Forwarded-For首部,其值为真正的客户端主机地址;此功能自动实现;

对于后端主机每一次访问日志信息中记录的客户端是代理服务器的ip地址,应该想要记录真正的客户端ip地址;

except <network>:来自于此网络的请求不添加;

header <name>:不使用默认的X-Forwarded-For,自定义的首部名称;即改名;


例如:

后端RS1,httpd配置文件,修改日志格式:

]# vim /etc/httpd/conf/httpd.conf

LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

技术分享


option forceclose

no option forceclose

启用或禁用活动连接,就是面向客户端连接时,响应完客户端后是否立即断开;


option httpclose

no option httpclose

启用或禁用被动http连接关闭,就是服务端是否关闭连接;

haproxy默认支持保持连接功能的,如果客户端不发请求连接也一直存在;

面向客户端一侧,如果强制不使用持久连接功能,可启用option httpclose;否则,要启用no option httpclose,且结合option http-server-close一同使用;


option http-keep-alive

no option http-keep-alive

是否启用保持连接功能;如果启用option http-keep-alive,要结合option http-server-close一同使用;


reqadd  <string> [{if | unless} <cond>]

向请求报文尾部添加自定义的header;


reqdel  <search> [{if | unless} <cond>]

reqidel <search> [{if | unless} <cond>]  (ignore case)

基于模式删除匹配到的请求报文首部中的header及其值;因为首部可能会影响调度算法,所以要删除;


<search>:搜索的是正则表达式;

reqidel:忽略字符大小写;



rspadd <string> [{if | unless} <cond>]

向响应报文尾部添加自定义的header;


rspdel  <search> [{if | unless} <cond>]

rspidel <search> [{if | unless} <cond>]  (ignore case)

基于模式删除匹配到的响应报文中的header及其值;


删除响应给客户端首部的Server的值,例如:

listen web

    log global

    bind *:80,*:8080

    balance roundrobin

    option httpchk

    maxconn 7700

    rspidel ^Server:.*

    errorfile 403 /tmp/403.html

    cookie web insert indirect nocache

    server web-RS1 172.18.11.11:80 check weight 1 maxconn 2000 maxqueue 200 cookie rs1

    server web-RS2 172.18.11.12:80 check weight 2 maxconn 5000 maxqueue 500 cookie rs2

技术分享


errorfile <code> <file>

设定错误页,响应码及响应的资源文件路径;

<code>:可为200, 400, 403, 408, 500, 502, 503, and 504.

<file>:是本地文件;


errorloc <code> <url>

设定错误页,响应码及响应的本地url;


errorloc302 <code> <url>

告诉客户端,错误页是重定向的本地url,这个url有可能是haproxy服务器自身提供的;


errorloc303 <code> <url>

不由haproxy服务器自己生成错误页,而是返回一个url,这个url可能在另一个服务器上;


使用acl结合自定义错误页,显示给客户端;


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

定义或补全一个访问列表;

acl要先定义后调用;


<aclname>:

指定acl的名称,可使用同一名称;可用大小写字母、短横线(-) 、下划线(_)、点号(.)、冒号(:);区分字符大小写;


<criterion>:匹配标准,可以基于分析请求报文中的任何属性信息,来作为判断一次请求报文是否符合此处所定义acl;标准非常多,如请求报文原地址、请求报文的首部各信息等;

四层获取匹配条件:

dst IP:目标地址匹配;

dst_port PORT:目标端口匹配;

src IP:源地址匹配;

src_port POST:源端口匹配;

[flags] :标志位;

[operator] :匹配后的操作符;

做布尔型匹配:其值0表示false,1表示true;

做整型匹配:可用操作符为:

eq:等于

ge:大于等于

gt:大于

le:小于

lt:小于等于

做字符串匹配:

-m str:精确匹配;

-m sub:做字串匹配;

-m beg:匹配前缀,即开头的字符串;

-m end:匹配后缀;

-m dir:匹配子路径;

-m dom:域名匹配;


指明多个匹配条件时,使用的逻辑符号:

与:隐式条件;

||:或

!:非


例如:

   acl url_static  path_beg         /static /images /img /css

   acl url_static  path_end         .gif .png .jpg .css .js

   acl host_www    hdr_beg(host) -i www

解释:

1.定义acl名称为url_static,条件匹配路径的开头,以/static /images /img /css开头都匹配;

2.cal名称相同,条件匹配路径结尾,以.gif .png .jpg .css .js结尾都匹配


use_backend <backend> [{if | unless} <condition>]

调用指定的后端主机;条件一般为acl;


default_backend <backend>

使用的默认后端主机;


haproxy实现简单的动静分离:


]# vim /etc/haproxy/haproxy.cfg


backend php

    balance roundrobin

#   cookie phpsession indirect nocache

    server phpsr1 172.18.11.112:80 check weight 1 cookie php1 maxconn 300

    server phpsr2 172.18.11.113:80 check weight 1 cookie php2 maxconn 600


backend web

    balance roundrobin

    server websr1 172.18.11.11:80 check maxconn 1000

    server websr2 172.18.11.12:80 check maxconn 1000


frontend frondphp

    bind *:80

    acl php_page path_end -i .php

#   acl php_page path_reg -i \.php$

    use_backend php if php_page

    default_backend web


listen stats

    bind *:9000

    stats enable


tcp-check connect [params*]

打开一个新连接;


block { if | unless } <condition>

阻塞7层请求;根据判断条件匹配;

<condition>就是acl;


http-request { allow | deny | tarpit | auth [realm <realm>] | redirect <rule> |

  add-header <name> <fmt> | set-header <name> <fmt> |

  del-header <name> | set-nice <nice> | set-log-level <level> |

  replace-header <name> <match-regex> <replace-fmt> |

  replace-value <name> <match-regex> <replace-fmt> |

  set-tos <tos> | set-mark <mark> |

  add-acl(<file name>) <key fmt> |

  del-acl(<file name>) <key fmt> |

  del-map(<file name>) <key fmt> |

  set-map(<file name>) <key fmt> <value fmt>

 }

 [ { if | unless } <condition> ]


基于7层做http的请求报文做访问控制;


例如:

acl nagios src 192.168.129.3

acl local_net src 192.168.0.0/16

acl auth_ok http_auth(L1)


http-request allow if nagios

http-request allow if local_net auth_ok

http-request auth realm Gimme if local_net auth_ok

http-request deny


对http的请求报文做控制,为白名单;


http-response { allow | deny | add-header <name> <fmt> | set-nice <nice> |

set-header <name> <fmt> | del-header <name> |

replace-header <name> <regex-match> <replace-fmt> |

replace-value <name> <regex-match> <replace-fmt> |

set-log-level <level> | set-mark <mark> | set-tos <tos> |

add-acl(<file name>) <key fmt> |

del-acl(<file name>) <key fmt> |

del-map(<file name>) <key fmt> |

set-map(<file name>) <key fmt> <value fmt>

}

[ { if | unless } <condition> ]


基于http的响应报文做访问控制;


例如:

acl key_acl res.hdr(X-Acl-Key) -m found


acl myhost hdr(Host) -f myhost.lst


http-response add-acl(myhost.lst) %[res.hdr(X-Acl-Key)] if key_acl

http-response del-acl(myhost.lst) %[res.hdr(X-Acl-Key)] if key_acl



以上是关于haproxy反代负载均衡的主要内容,如果未能解决你的问题,请参考以下文章

nginx做前端反代负载均衡,后端httpd+tomcat

Nginx+Keepalived 实现反代 负载均衡 高可用(HA)配置

apache分别基于三种方案实现tomcat的代理负载均衡及会话绑定

Linux企业运维——haproxy负载均衡

负载均衡之haproxy-----haproxy负载均衡+pcs高可用+fence

初识千万级高并发负载均衡软件HaProxy