1. 程序环境:
- 程序:
/usr/sbin/haproxy
- 主配置文件:
/etc/haproxy/haproxy.cfg
- Unit file:
/usr/lib/systemd/system/haproxy.service
2. 配置段:
-
global:
全局配置段
进程及安全配置相关的参数
性能调整相关参数
Debug参数 -
proxies:
代理配置段
defaults:为frontend, listen, backend提供默认配置;
fronted:前端,相当于nginx, server {}
backend:后端,相当于nginx, upstream {}
listen:同时拥前端和后端
3. global配置参数:
为haproxy进程级别参数,且常与其运行的OS相关
大多数不需修改;haproxy进程相关的属性定义,且多数与HAProxy所运行的OS相关;进程管理及安全相关的参数:
chroot:禁锢,修改haproxy的工作目录至指定的目录并在放弃权限之前执行chroot()操作,可以提升haproxy的安全级别,不过需要注意的是要确保指定的目录为空目录且任何用户均不能有写权限;
daemon:运行为守护进程;让haproxy以守护进程的方式工作于后台,其等同于-D选项的功能;当然,也可在命令行中以-db选项将其禁用;
user:同uid,但使用的是用户名;
group:同gid,不过指定的是组名;
uid <number>:以指定的UID身份运行haproxy进程;
gid <number>:以指定的GID运行haproxy,建议使用专用于运行haproxy的GID,以免因权限问题带来风险;
*log:定义全局的syslog服务器,最多可定义两个,用于实现将haproxy产生的日志发往此服务器予以存储;
log <address> <facility> [max level [min level]]
log-send-hostname [<string>]:在syslog信息的首部添加当前主机名,可以为string指定的名称,也可省略使用当前主机名;
nbproc <number>:指明要启动的haproxy进程的数量;默认1个;大于1个只能以守护进程启动;通常不建议启动多个;鉴于调试困难等多方面原因,一般只在单进程仅能打开少数文件描述符的场景中才使用多进程模式;
pidfile:
ulimit-n <number>:设定每个haproxy进程所能打开的最大文件(描述符)数量;应该大于maxconn值,haproxy自动动计算此数据为其设定合理值;不用调整;
stats:
node:定义当前节点的名称,用于HA场景中多haproxy进程共享同一个IP地址时;
description:当前实例的描述信息;
4. 性能调整相关的参数:
*maxconn <number>:设定单个haproxy进程所能接受的最大并发连接数;其等同于命令行选项-n;ulimit -n自动计算的结果正是参照此参数设定的;
maxpipes <number>:最大管道数量,基于内核的报文重组时,使用的内存空间;haproxy使用pipe机制完成实现内核级tcp报文重组,此选项用于设定每进程所能够使用的最大pipe数量;每个pipe会打开两个文件描述符,因此,ulimit-n会自动计算时会根据需要调大此值;默认为值为:maxconn/4,其通常会显得过大;
noepoll:在Linux系统上禁用epoll事件机制;调试目的才关闭;
nokqueue:在BSE系统上禁用kqueue事件机制;调试目的才关闭;
nopoll:禁用poll事件机制;调试目的才关闭;
nosepoll:在Linux系统上禁用启发式epoll事件机制;调试目的才关闭;
nosplice:禁用在Linux套接字上使用内核级tcp报文重组功能,调试目的才关闭;这会导致更多的recv/send系统调用;不过在Linux 2.6.25-28系列的内核上,tcp重组功能有bug存在;
*spread-checks <0..50>:在haproxy后端有着众多服务器的场景中,在精确的时间间隔后统一对众多服务器进行健康状况检查可能会带来意外问题;此选项用于将其检查的时间间隔长度上增加或减少一定的随机时长;百分比,表示时间间隔的百分之几;打散健康状态检测机制发出的时间,提前或延后,一般不大于检测时间的50%;0表示不散开,到时间点就检测;
tune.bufsize:设定buffer缓冲区大小;同样的内存条件小,较小的值可以让haproxy有能多的并发连接,较大的值可以让某些应用程序使用较大的cookie信息;默认为16384,其可以在编译时修改,不过强烈建议使用默认值;
tune.chksize:进程缓冲区大小;设定检查缓冲区的大小,单位为字节,更大的值有助于在较大的页面中完成基于字符串后模式的文本查找,但也会占用更大的系统资源;不建议修改;
tune.maxaccept:设定haproxy进程内核调度运行时一次性可以接受的连接的个数,较大的值可以带来较大的吞吐率,默认在单进程模式下为100,多进程模式下为8,设定为-1可以禁止此限制;一般不建议修改;
tune.maxpollevents:设定一次系统调用可以处理的事件最大数,默认值取决于OS,其值小于200时,可节约带宽,但会略微增大网络延迟,而大于200时会降低延迟,但会稍稍增加网络带宽的占用量;
tune.maxrewrite:设定为首部重写或追加而预留的缓存空间,建议使用1024左右的大小,在需要使用更大的空间时,haproxy会自动增加其值;
...tune.rcvbuf.client:面向客户端的接收缓冲;
tune.sndbuf.client:面向客户端的发送缓冲;
tune.rcvbuf.server:设定内核套接字中服务端或客户端接收缓冲的大小,单位为字节;强烈建议使用默认值;面向服务器端的接收缓冲;
tune.sndbuf.server:面向服务器端的发送缓冲;
5. debug相关的参数:
- debug:详细输出信息;
- quiet:静默模式;
简单示例:
准备2各后端主机,并配置index.html
[root@backend1 ~]# vim /var/www/html/index.html
<h1>backend server 192.168.43.13</h1>
[root@backend2 ~]# vim /var/www/html/index.html
<h1>backend server 192.168.43.14</h1>
[root@haproxy ~]# yum -y install haproxy #安装
[root@haproxy ~]# vim /etc/rsyslog.conf #配置日志服务器
$ModLoad imudp
$UDPServerRun 514
local2.* /var/log/haproxy.log
[root@haproxy ~]# touch /var/log/haproxy.log
[root@haproxy ~]# chown haproxy.haproxy /var/log/haproxy.log
[root@haproxy ~]# systemctl restart rsyslog.service
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg #修改配置文件,添加如下内容
frontend web
bind *:80
default_backend websrvs
backend websrvs
balance roundrobin
server srv1 192.168.43.13:80 check
server srv2 192.168.43.14:80 check
访问测试:
[root@localhost ~]# for i in {1..10}; do curl http://192.168.43.11; done
<h1>backend server 192.168.43.14</h1>
<h1>backend server 192.168.43.13</h1>
<h1>backend server 192.168.43.14</h1>
<h1>backend server 192.168.43.13</h1>
<h1>backend server 192.168.43.14</h1>
<h1>backend server 192.168.43.13</h1>
<h1>backend server 192.168.43.14</h1>
<h1>backend server 192.168.43.13</h1>
<h1>backend server 192.168.43.14</h1>
<h1>backend server 192.168.43.13</h1>
6. proxies代理配置段参数
<1>. bind :Define one or several listening addresses and/or ports in a frontend.在前端定义一个或多个监听地址和/或端口
bind [<address>]:<port_range> [, ...] [param*]
<address>:
支持ipv4地址,ipv6地址,unix socket地址,abns(abstract namespace抽象名称空间)仅用于Linux系统;
<port_range>:
可以是一个端口,例如::80; 也可是一个端口范围,例如:2000-2100;
<path>:
使用unix socket套接字文件;
[param*]:
参数;
<2>. balance:设定调度方法,用在default,listen,backend中;
balance <algorithm> [<arguments>]
balance url_param <param> [check_post [<max_wait>]]
-
指定基于url的参数做调度;
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> 片段,同一页面上的不同段落锚定
<3>.server:定义后端主机的各服务器及其选项;
-
<name>:
服务器的内部名称,仅在haproxy中使用;主要作用会出现在日志及警告信息中,可用来判断故障服务器,如果设定了http-send-server-name,它还将被添加至发往此服务器的请求首部当中; -
<address>:
服务器的ip地址,支持使用主机名; -
[:[port]]:
端口映射;省略时,表示与bind的端口相同; -
[param*]:
可选参数;backup:
设定为备用服务器,相当于sorry server;仅在所有服务器均不可用时,才启用;check:
对后端服务器做健康状态检测,无check时,表示假设后端主机始终可用,同时可使用辅助参数有很多;健康状态检测又三种:网络层检测、传输层检测(端口在未必服务正常,精确度不高)、应用层检测;addr:
通过此地址进行健康状态检测;port <port>
:通过此端口进行健康状态检测;inter <delay>
:连续两次检测之间的时间间隔,默认2000毫秒;每隔多长时间做一次健康检测;fastinter <delay>
:如果不指明inter,为2秒钟,downinter <delay>
:fall <count>
:连续多少次的失败检测将标记服务器检测为dead;默认3次;rise <count>
:连续多少次的成功检测将标记服务器为available;默认2次;httpchk:
基于http协议进行健康状态检测;是独立的参数;
类似的还有"smtpchk", "mysql-check", "pgsql-check" and "ssl-hello-chk"分别用来定义7层检测的;check-send-proxy
check-ssl:
与后端通信使用ssl协议时此行用到;ciphers <ciphers>
:指明加密方法;ca-file <cafile>
:表示haproxy与后端服务器通信时基于ssl方式,指明ca证书文件;cookie <value>
:为当前server指定cookie值,用于实现基于cookie会话的粘性;此值会在set cookie时发给客户端;客户端每次请求时就会附加这个cookie;haproxy每次收到请求后,都会检查,进行比对,并且比对完成后,将请求发往比对成功的服务器上;
客户端发来的请求报文中,如果带有cookie,这个cookie信息会跟每一个后端服务器的cookie进行比对,如果比对成功就会把用户请求,始终发往比对成功的这台服务器上去;
在haproxy上为每一个后端主机,通过server定义时,为每一个后端主机定义一个唯一标识,这个唯一标识是插入的cookie信息,作用是,如果后端服务器响应用户请求至客户端时,这个响应报文中会set cookie,就是告诉客户端下次再来访问就使带着这个cookie,这个set cookie信息中将会包含在haproxy上为这个服务器指明的cookie标记符,每一个服务器要使用不同的cookie标记符;
例如,第一个主机标记为server1,第二个服务器主机标记为server2等等,如果是服务器1响应的,set cookie时为,就把server1响应给客户端了;于是,客户端在浏览器中就有了cookie信息,而cookie的值一大堆字符串就包含了server1;所以,客户端一旦有了cookie,每一次向haproxy请求,都会附带此前被设定的cookie当中就包含server1;于是,当haproxy收到请求以后,通过分析发现,里面带的cookie是server1,而后端主机都有cookie,比较找到哪台服务器是server1,就直接发给该服务器;这个意义就叫会话的粘性;
粘性有两种级别,一种是在ip地址上决定,来自于同一地址的始终发往同一后端主机,第二种就是来自于同一用户的会话始终发往同一后端主机;调度粒度更精细到了cookie级别;disabled
:表示禁用,类似于varnish中标记为down状态;id <value>
:为每个服务器设置一个持久ID,是基于id的会话粘性才会用到;force-tlsv10
:强制使用协议版本;maxconn <maxconn>
:当前服务器支持的最大并发连接数,超出此值的连接将被放置请求队列中;maxqueue <maxqueue>
:当前服务器的队列上限;minconn <minconn>
:如果设定了此参数,那么,最大值就成为动态的,可以根据后端服务器负载状态动态调整;non-tlsv
:禁止使用协议的版本;observe <mode>
:用于通过观察服务器端的流量来做健康状态判断;默认是禁用的,因为会带来资源使用压力;-
mode {tcp | http | health}
:- 定义haproxy的工作模式;
- tcp:基于layer4实现代理;可代理mysql, pgsql, ssh, ssl等协议;
- http:仅当代理的协议为http时使用;
- health:工作为健康状态检查的响应模式,当连接请求到达时回应“OK”后即断开连接;
- 定义haproxy的工作模式;
-
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响应码;
例如:server srv1 192.168.1.1:80 redir http://image1.mydomain.com checkweight <weight>
:服务器的权重;
<4>. stats:统计接口启用相关的参数
-
·stats enable:启用统计页,基于默认的参数启用stats page;
- status uri:/haproxy?stats
- status realm:"HAProxy Statistics"
- stats auth:no authentication
- stats scope:no restriction
stats auth <user>:<passwd>
:认证时的账号和密码,可使用多次stats realm <realm>
:启用统计信息并设置身份验证领域;使用字符串中有空格时,要用转义符或加双引号;stats uri <prefix>
:自定义stats page uristats refresh <delay>
:设定自动刷新时间;默认单位秒;stats show-desc [ <desc> ]
:设定显示状态页的描述信息stats admin { if | unless } <cond>
:启动stats page 中的管理功能-
stats show-legends
:在统计页添加信息;可添加如下:- cap:capabilities(proxy)
- mode: one of tcp,http or health(proxy)
- id:SNMP ID(proxy, socket, server)
- IP:(socket, server)
- cookie:(socket, server)
-
stats hide-version
:在统计页隐藏版本信息示例: listen stats bind *:9009 stats enable stats uri /haproxyadmin?stats stats realm haproxy\ statistics stats auth admin:pass stats show-desc This is admin area stats hide-version stats admin if TRUE
<5>. cookie:基于cookie进行会话保持;
cookie <name> [ rewrite | insert | prefix ] [ indirect ] [ nocache ] [ postonly ] [ preserve ] [ httponly ] [ secure ] [ domain <domain> ]* [ maxidle <idle> ] [ maxlife <life> ]
-
<name>
:is the name of the cookie which will be monitored, modified or inserted in order to bring persistence.用于指明cookie中的某个名称,这个名称定义了那一段cookie信息是用来做会话粘性时被监控、修改、或者插入信息以实现持久性的; -
rewirte
:重写;整个cookie信息将会被haproxy重写,并在内部加上服务器id信息,当然,也有可能把某些信息依然放进去,只是把其中的某些项改了;相当于把insert和prefix结合使用; -
insert
:插入;在原有的cookie中插入; -
prefix
:添加前缀;把cookie信息插入在原有cookie信息的最左侧; - 分别表示跟cache Control相关时,在什么场景下cookie有效:
- indirect:
- nocache:当使用insert操作时,当客户端经由一个代理连接haproxy主机时,推荐使用此选项;用来操作对应的cache标记来判定对应信息是否能够作为重写标准;
- postonly
- preserve:服务器可以保留某个指定的cookie标记,以实现基于此信息的转发;
- httponly
- secure:指示haproxy在insert时添加一个secure cookie标记;作用在于不允许后端服务器操作里面的cookie信息;
- domain <domain>:对应的cookie对应在哪个域上;
- maxidle <idle>
- maxlife <life>
官方示例:
cookie JSESSIONID prefix
cookie SRV insert indirect nocache
cookie SRV insert postonly indirect
cookie SRV insert indirect nocache maxidle 30m maxlife 8h
解释:
1.名称为SESSIONID,在原有的这个名称之前,基于prefix方式,加上当前server的id;就是第一次调度时,调度哪个server上,把哪个server id给它插入到原有cookie数据之前;
2.表示插入的名称为SRV,基于insert方式操作,同时定义了indirect和nocache,此种方式比较常见;
示例:
backend websrvs
cookie WEBSRV insert nocache indirect
设定的WEBSRV相当于一个变量,调度到哪台服务器,就把哪台的服务器的cookie值赋给WEBSRV;
server srv1 172.16.100.6:80 weight 2 check rise 1 fall 2 maxconn 3000 cookie srv1
server srv2 172.16.100.7:80 weight 1 check rise 1 fall 2 maxconn 3000 cookie srv2
<6>. option:
-
option forwardfor [ except <network> ] [ header <name> ] [ if-none ]
:把发往backend server的请求报文中添加“X-Forwarded-For”首部,其值为真正的客户端主机地址;此功能自动实现; 对于后端主机每一次访问日志信息中记录的客户端是代理服务器的ip地址,应该记录真正的客户端ip地址;[ except <network> ]
:请求报文来自此处指定的网络时不予添加此首部-
[ header <name> ]
:使用自定义的首部名称,而非“X-Forwarded-For“示例: [root@backend2 ~]# vim /etc/httpd/conf/httpd.conf #编辑后端backend2的配置文件,修改日志格式 LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined 浏览器访问:http://192.168.43.11/index.html [root@backend2 ~]# tail -4 /var/log/httpd/access_log #查看后端主机日志的区别 192.168.43.11 - - [25/Sep/2018:11:19:16 -0400] "GET / HTTP/1.1" 200 38 "-" "Mozilla/5.0 (Wws NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari.36 Edge/17.17134" 192.168.43.100 - - [25/Sep/2018:11:19:56 -0400] "GET / HTTP/1.1" 200 38 "-" "Mozilla/5.0 (ows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safar7.36 Edge/17.17134"
option forceclose
;no option forceclose
:启用或禁用活动连接,就是面向客户端连接时,响应完客户端后是否立即断开;option httpclose
;no option httpclose
:启用或禁用被动http连接关闭,就是服务端是否关闭连接; haproxy默认支持保持连接功能的,如果客户端不发送请求连接也一直存在;option http-keep-alive
;no option http-keep-alive
:是否启用保持连接功能;如果启用http-keep-alive,要结合option http-server-close一同使用option http-server-close
;no option http-server-close
:在服务器端启用或禁用HTTP连接关闭
<7>.error:
- `errorfile <code> <file>:返回一个自定义的错误页,而不是haproxy生成的;
-
<code>
:is the HTTP status code. Currently, HAProxy is capable of generating codes 200, 400, 403, 408, 500, 502, 503, and 504. -
<file>
:designates a file containing the full HTTP response.
-
-
errorloc <code> <url>; errorloc302 <code> <url>
:
<8>.req相关
reqadd <string> [{if | unless} <cond>]
: Add a header at the end of the HTTP request;;-
rspadd <string> [{if | unless} <cond>]
: Add a header at the end of the HTTP responserspadd X-Via:\ HAPorxy
reqdel <search> [{if | unless} <cond>]
reqidel <search> [{if | unless} <cond>] (ignore case)
:
Delete all headers matching a regular expression in an HTTP request-
rspdel <search> [{if | unless} <cond>]
rspidel <search> [{if | unless} <cond>] (ignore case)
:
Delete all headers matching a regular expression in an HTTP responserspidel Server.*
<9>.log:日志系统
-
log global 调用全局日志
log <address> [len <length>] <facility> [<level> [<minlevel>]]
-
<address>:
依然是日志服务器的地址,同全局配置; -
<facility>:
依然是发往日志服务器指定的设施来记录日志; -
<level> [<minlevel>]:
指明级别,记录的日志范围;
-
no log:不记录日志;
注意:为每个实例启用事件和流量日志,可用于所有区段(代理),每个实例最多指定两个log目标;
用来指明前端代理的日志发往的路径;无论是全局还是每个代理配置,其中最多可以使用2个日志存放位置,但是如果全局定义了2个,在代理中又使用了log global,则这个代理上就不能再定义日志存放位置了;log-format <string>
:日志格式-
capture cookie <name> len <length>
Capture and log a cookie in the request and in the response.记录请求及响应报文的cookie于日志中;-
<name>:
cookie信息的开头字符; -
<length>:
记录cookie的长度,单位字节;
-
-
capture request header <name> len <length>
Capture and log the last occurrence of the specified request header.记录请求报文中的指定的首部的值于日志中;capture request header X-Forwarded-For len 15
-
capture response header <name> len <length>
Capture and log the last occurrence of the specified response header.记录响应给客户端的响应报文中的指定的首部的值于日志中;capture response header Content-length len 9 capture response header Location len 15
<10>. 传输压缩机制;
-
compression algo <algorithm> ...
:启用http协议的压缩机制,指明压缩算法gzip,deflage
支持的algo:- identity:通常仅debug时使用
- gzip:使用glib库,也支持zlib库
- deflate:支持zlib库,信息压缩
-
compression type <mime type> ...
:指明压缩的MIMI类型;通常仅压缩文本类型的资源;例如,text/html,text/plain; -
compression offload
:卸载器;例如与客户端之间传输可以压缩,但与上游服务器不再压缩,反之亦然,类似这种概念;
<11>. 对后端服务器做http协议的健康状态检测:
option httpchk option httpchk <uri> option httpchk <method> <uri> option httpchk <method> <uri> <version>
定义基于http协议的7曾健康状态检测机制;
http-check expect [!] <match> <pattern>
:让HTTP健康检查考虑响应内容或特定状态码。
<12>. 连接超时时长:
timeout client <timeout>
Set the maximum inactivity time on the client side. 默认单位是毫秒;timeout server <timeout>
Set the maximum inactivity time on the server side.timeout http-keep-alive <timeout>
持久连接的持久时长;timeout http-request <timeout>
Set the maximum allowed time to wait for a complete HTTP requesttimeout connect <timeout>
Set the maximum time to wait for a connection attempt to a server to succeed.timeout client-fin <timeout>
Set the inactivity timeout on the client side for half-closed connections.timeout server-fin <timeout>
Set the inactivity timeout on the server side for half-closed connections.
<13>.其他相关参数
use_backend <backend> [{if | unless} <condition>]
Switch to a specific backend if/unless an ACL-based condition is matched.
当符合指定的条件时使用特定的backend;-
block { if | unless } <condition>
Block a layer 7 request if/unless a condition is matchedacl invalid_src src 172.16.200.2 block if invalid_src errorfile 403 /etc/fstab
http-request { allow | deny } [ { if | unless } <condition> ]
Access control for Layer 7 requeststcp-request connection {accept|reject} [{if | unless} <condition>]
Perform an action on an incoming connection depending on a layer 4 condition
7. acl:Access Control Lists
The use of Access Control Lists (ACL) provides a flexible solution to perform content switching and generally to take decisions based on content extracted from the request, the response or any environmental status.他使用访问控制列表(ACL)提供了一个灵活的解决方案来执行内容切换,通常根据从请求、响应或任何环境状态中提取的内容做出决策.
acl <aclname> <criterion> [flags] [operator] [<value>] ...
-
<aclname>:
指定acl名称,可以使用大小写字母、短横线、下划线、点号、冒号;区分字符大小写。 -
<criterion>:
匹配标准,可以基于分析请求报文中的任何属性信息,来作为判断一次请求报文是否符合此处所定义acl;标准非常多,如请求报文原地址、请求报文的首部各信息等; -
[flags]
: 标志位;可以用以下标志位做值匹配时,基于什么标准来控制-
-i
: ignore case during matching of all subsequent patterns.在匹配所有后续模式时忽略大小写;比较时使用。 -
-m
: use a specific pattern matching method;指定使用特定的模式匹配方式; -
-n
: forbid the DNS resolutions;禁止DNS解析; -
-u
: force the unique id of the ACL;强制acl的唯一id -
--
: force end of flags. Useful when a string looks like one of the flags. 强制结束标志。当字符串看起来像某个标志时非常有用
-
-
[operator] :
匹配后的操作符;- 做布尔型匹配:其值0表示false,1表示true;
- 做整型匹配:可用操作符为:
- eq:等于
- ge:大于等于
- gt:大于
- le:小于
- lt:小于等于
- 做字符串匹配:
- -m str:精确匹配;
- -m sub:做字串匹配;
- -m beg:匹配前缀,即开头的字符串;
- -m end:匹配后缀;
- -m dir:匹配子路径;
- -m dom:域名匹配;
- acl作为条件时的逻辑关系:
- 与(AND): 隐式条件
- 或(OR):explicit with the "or" keyword or the "||" operator
- 非:Negation with the exclamation mark ("!")
-
<value>
:值;- boolean:指定true或false;
- integer or integer range:指定整数或范围;
- IP address / network:指定地址或地址范围;
- string (exact, substring, suffix, prefix, subdir, domain):指定精确字符串、子串、前缀、后缀、...
- regular expression:指定正则表达式模式;
- hex block
- 注意:两个acl的名称可以一样,二者合并起来作为一个条件;是或关系,即同名的acl的条件,满足第一个或满足第二个,表示都是能被匹配到;
criterion
常见的匹配标准
- 四层获取匹配条件:
- dst IP:目标地址匹配;
- dst_port PORT:目标端口匹配;
- src IP:源地址匹配;
- src_port POST:源端口匹配;
- dst_conn : integer:目标连接数量匹配;
- 七层获取匹配条件:
- path : string;这将提取请求的URL路径,该路径从第一个斜杠开始,在问号前面结束(不包含主机部分);即表示匹配检查用户请求的path路径。
- path : exact string match;精确匹配某个url路径
- path_beg : prefix match;匹配某个url路径的前缀
- path_dir : subdir match;匹配某个url路径的子路径
- path_dom : domain match 匹配某个url路径的域名
- path_end : suffix match 匹配某个url路径的后缀
- path_len : length match 匹配某个url路径的长度
- path_reg : regex match 匹配某个url路径的正则表达式
- path_sub : substring match 匹配某个url路径的子串
- url : string;表示匹配检查用户请求的url。一个典型的用法是使用具有预取功能的缓存,以及需要从数据库聚合多个信息并将其保存在缓存中的门户。
- url : exact string match
- 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
-
req.hdr([<name>[,<occ>]]) :
string; 这将在HTTP请求中提取报头<name>
的最后一次出现。-
hdr([<name>[,<occ>]])
: exact string match -
hdr_beg([<name>[,<occ>]])
: prefix match;匹配指定报文首部的值以给定的字符开头 -
hdr_dir([<name>[,<occ>]])
: subdir match;匹配指定报文首部的值以给定的子路径 -
hdr_dom([<name>[,<occ>]])
: domain match;匹配指定报文首部的值以给定的域名 -
hdr_end([<name>[,<occ>]])
: suffix match;匹配指定报文首部的值以给定的后缀 -
hdr_len([<name>[,<occ>]])
: length match;匹配指定报文首部的值以给定的长度 -
hdr_reg([<name>[,<occ>]])
: regex match;匹配指定报文首部的值以给定的正则式 -
hdr_sub([<name>[,<occ>]])
: substring match 匹配指定报文首部的值以给定的子串
-
-
req.cook([<name>]) :
string:匹配请求报文中cookie的名字是否符合给定的值;-
cook([<name>]):
做精确cookie名称匹配 -
cook_beg([<name>]):
做cookie的前缀匹配 -
cook_dir([<name>]):
做cookie的子路径匹配 -
cook_dom([<name>]):
做cookie的域名匹配 -
cook_end([<name>]):
做cookie的后缀匹配 -
cook_len([<name>]):
做cookie的长度匹配 -
cook_reg([<name>]):
做cookie的正则式匹配 -
cook_sub([<name>]):
做cookie的子串匹配
-
- path : string;这将提取请求的URL路径,该路径从第一个斜杠开始,在问号前面结束(不包含主机部分);即表示匹配检查用户请求的path路径。
-
Pre-defined ACLs:内建的acl变量
ACL name Equivalent to Usage FALSE always_false never match HTTP req_proto_http match if protocol is valid HTTP HTTP_1.0 req_ver 1.0 match HTTP version 1.0 HTTP_1.1 req_ver 1.1 match HTTP version 1.1 HTTP_CONTENT hdr_val(content-length) gt 0 match an existing content-length HTTP_URL_ABS url_reg ^[^/:]*:// match absolute URL with scheme HTTP_URL_SLASH url_beg / match URL beginning with "/" HTTP_URL_STAR url * match URL equal to "*" LOCALHOST src 127.0.0.1/8 match connection from local host METH_CONNECT method CONNECT match HTTP CONNECT method METH_GET method GET HEAD match HTTP GET or HEAD method METH_HEAD method HEAD match HTTP HEAD method METH_OPTIONS method OPTIONS match HTTP OPTIONS method METH_POST method POST match HTTP POST method METH_TRACE method TRACE match HTTP TRACE method RDP_COOKIE req_rdp_cookie_cnt gt 0 match presence of an RDP cookie REQ_CONTENT req_len gt 0 match data in the request buffer TRUE always_true always match WAIT_END wait_end wait for end of content analysis
8. 基于acl实现智能负载均衡
准备两个静态虚拟主机:
[root@websrvs ~]# cd /etc/httpd/conf.d/
[root@websrvs conf.d]# vim vhost1.conf
<VirtualHost *:80>
ServerName www.ilinux.io
DocumentRoot "/data/web/host1"
<Directory "/data/web/host1">
Options None
AllowOverride None
require all granted
</Directory>
</VirtualHost>
Listen 8080
<VirtualHost *:8080>
ServerName www.inux.io
DocumentRoot "/data/web/host2"
<Directory "/data/web/host2">
Options None
AllowOverride None
require all granted
</Directory>
</VirtualHost>
给两个虚拟主机准备2个主页文件index.html:
[root@websrvs conf.d]# mkdir /data/web/host{1,2}
[root@websrvs ~]# vim /data/web/host1/index.html
<h1>www.ilinux.io</h1>
[root@websrvs ~]# vim /data/web/host2/index.html
<h1>www.inux.io</h1>
准备两个动态虚拟主机:
[root@phpsrvs conf.d]# vim vhost1.conf
<VirtualHost *:80>
ServerName www.ilinux.com
DocumentRoot "/data/web/host1"
<Directory "/data/web/host1">
Options None
AllowOverride None
require all granted
</Directory>
</VirtualHost>
Listen 8080
<VirtualHost *:8080>
ServerName www.inux.com
DocumentRoot "/data/web/host2"
<Directory "/data/web/host2">
Options None
AllowOverride None
require all granted
</Directory>
</VirtualHost>
[root@phpsrvs ~]# yum -y install php
准备2各动态主页index.php
[root@phpsrvs ~]# vim /data/web/host1/index.php
<h1>www.ilinux.com</h1>
<?php
phpinfo();
?>
[root@phpsrvs ~]# vim /data/web/host2/index.php
<h1>www.inux.com</h1>
<?php
phpinfo();
?>
[root@phpsrvs ~]# systemctl start httpd.service
安装配置haproxy:
[root@haproxy ~]# yum -y install haproxy
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
frontend https
bind *:80
# bind *:443 ssl crt /etc/haproxy/certs/haproxy.pem #实现基于ssl的会话
# redirect scheme https if !{ ssl_fc }
acl php_page path_end -i .php
use_backend phpsrvs if php_page
default_backend websrvs
backend websrvs
balance roundrobin
server srv1 192.168.43.14:80 check
server srv2 192.168.43.14:8080 check
backend phpsrvs
balance roundrobin
# cookie php insert indirect nocache
server srv1 192.168.43.13:80 check cookie ph1
server srv2 192.168.43.13:8080 check cookie ph2
listen stats
bind *:9009
stats enable
stats uri /haproxyadmin?stats
stats realm haproxy\ statistics
stats auth admin:pass
stats show-desc This is admin area
stats hide-version
stats admin if TRUE
[root@haproxy ~]# systemctl start haproxy.service
#使用curl访问静态服务器测试:
[root@haproxy ~]# for i in {1..10};do curl http://192.168.43.11; done;
<h1>www.inux.io</h1>
<h1>www.ilinux.io</h1>
<h1>www.inux.io</h1>
<h1>www.ilinux.io</h1>
<h1>www.inux.io</h1>
<h1>www.ilinux.io</h1>
<h1>www.inux.io</h1>
<h1>www.ilinux.io</h1>
<h1>www.inux.io</h1>
<h1>www.ilinux.io</h1>
使用浏览器访问测试: