环境说明:
组件 | 主机 | 备注 |
Haproxy | 192.168.32.200 | 下载地址 |
sharding-proxy | 192.168.1.166:3307 | |
sharding-proxy | 192.168.1.166:3308 | |
sharding所在宿主机 | 192.168.1.166 | |
cd /home mkdir haproxy cd /home/haproxy
1.添加用户
#添加haproxy组 groupadd -r haproxy #创建nginx运行账户haproxy并加入到haproxy组,不允许haproxy用户直接登录系统 useradd -r -g haproxy -M -s /sbin/nologin haproxy |
上次下载好的安装包到home/haproxy目录下
示例配置说明 |
global # 全局参数的设置 log 127.0.0.1 local0 info # log语法:log [max_level_1] # 全局的日志配置,使用log关键字,指定使用127.0.0.1上的syslog服务中的local0日志设备, 记录日志等级为info的日志 user haproxy group haproxy # 设置运行haproxy的用户和组,也可使用uid,gid关键字替代之 daemon # 以守护进程的方式运行 nbproc 16 # 设置haproxy启动时的进程数,根据官方文档的解释,我将其理解为:该值的设置应该和服务 #器的CPU核心数一致,即常见的2颗8核心CPU的服务器,即共有16核心,则可以将其值设置为: #<=16 ,创建多个进程数,可以减少每个进程的任务队列,但是过多的进程数也可能会导致进程 #的崩溃。这里我设置为16 maxconn 4096 # 定义每个haproxy进程的最大连接数 ,由于每个连接包括一个客户端和一个服务器端,所以单 #个进程的TCP会话最大数目将是该值的两倍。 #ulimit -n 65536 # 设置最大打开的文件描述符数,在1.4的官方文档中提示,该值会自动计算,所以不建议进行 #设置 pidfile /var/run/haproxy.pid # 定义haproxy的pid defaults # 默认部分的定义 mode http # mode语法:mode {http|tcp|health} 。http是七层模式,tcp是四层模式,health是健康检测 #,返回OK log 127.0.0.1 local3 err # 使用127.0.0.1上的syslog服务的local3设备记录错误信息 retries 3 # 定义连接后端服务器的失败重连次数,连接失败次数超过此值后将会将对应后端服务器标记为 #不可用 option httplog # 启用日志记录HTTP请求,默认haproxy日志记录是不记录HTTP请求的,只记录“时间[Jan 5 13 #:23:46] 日志服务器[127.0.0.1] 实例名已经pid[haproxy[25218]] 信息[Proxy http_80_in s #topped.]”,日志格式很简单。 option redispatch # 当使用了cookie时,haproxy将会将其请求的后端服务器的serverID插入到cookie中,以保证 #会话的SESSION持久性;而此时,如果后端的服务器宕掉了,但是客户端的cookie是不会刷新的 #,如果设置此参数,将会将客户的请求强制定向到另外一个后端server上,以保证服务的正常 option abortonclose # 当服务器负载很高的时候,自动结束掉当前队列处理比较久的链接 option dontlognull # 启用该项,日志中将不会记录空连接。所谓空连接就是在上游的负载均衡器或者监控系统为了 #探测该服务是否存活可用时,需要定期的连接或者获取某一固定的组件或页面,或者探测扫描 #端口是否在监听或开放等动作被称为空连接;官方文档中标注,如果该服务上游没有其他的负 #载均衡器的话,建议不要使用该参数,因为互联网上的恶意扫描或其他动作就不会被记录下来 option httpclose # 这个参数我是这样理解的:使用该参数,每处理完一个request时,haproxy都会去检查http头 #中的Connection的值,如果该值不是close,haproxy将会将其***,如果该值为空将会添加为: #Connection: close。使每个客户端和服务器端在完成一次传输后都会主动关闭TCP连接。与该 #参数类似的另外一个参数是“option forceclose”,该参数的作用是强制关闭对外的服务通道 #,因为有的服务器端收到Connection: close时,也不会自动关闭TCP连接,如果客户端也不关 #闭,连接就会一直处于打开,直到超时。 contimeout 5000 # 设置成功连接到一台服务器的最长等待时间,默认单位是毫秒,新版本的haproxy使用timeout #connect替代,该参数向后兼容 clitimeout 3000 # 设置连接客户端发送数据时的成功连接最长等待时间,默认单位是毫秒,新版本haproxy使用 #timeout client替代。该参数向后兼容 srvtimeout 3000 # 设置服务器端回应客户度数据发送的最长等待时间,默认单位是毫秒,新版本haproxy使用 #timeout server替代。该参数向后兼容 listen status # 定义一个名为status的部分,可以在listen指令指定的区域中定义匹配规则和后端服务器ip, #相当于需要在其中配置frontend,backend的功能。一般做tcp转发比较合适,不用太多的规则 #匹配。 bind 0.0.0.0:1080 # 定义监听的套接字 mode http # 定义为HTTP模式 log global # 继承global中log的定义 stats refresh 30s # stats是haproxy的一个统计页面的套接字,该参数设置统计页面的刷新间隔为30s stats uri /admin?stats # 设置统计页面的uri为/admin?stats stats realm Private lands # 设置统计页面认证时的提示内容 stats auth admin:password # 设置统计页面认证的用户和密码,如果要设置多个,另起一行写入即可 stats hide-version # 隐藏统计页面上的haproxy版本信息 frontend http_80_in # 定义一个名为http_80_in的前端部分,haproxy会监听bind的端口 bind 0.0.0.0:80 # http_80_in定义前端部分监听的套接字 mode http # 定义为HTTP模式 log global # 继承global中log的定义 option forwardfor # 启用X-Forwarded-For,在requests头部插入客户端IP发送给后端的server,使后端server获 #取到客户端的真实IP acl static_down nbsrv(static_server) lt 1 # 定义一个名叫static_down的acl,当backend static_sever中存活机器数小于1时会被匹配到 acl php_web url_reg /*.php$ #acl php_web path_end .php # 定义一个名叫php_web的acl,当请求的url末尾是以.php结尾的,将会被匹配到,上面两种写 #法任选其一 acl static_web url_reg /*.(css|jpg|png|jpeg|js|gif)$ #acl static_web path_end .gif .png .jpg .css .js .jpeg # 定义一个名叫static_web的acl,当请求的url末尾是以.css、.jpg、.png、.jpeg、.js、.gif #结尾的,将会被匹配到,上面两种写法任选其一 use_backend php_server if static_down # 如果满足策略static_down时,就将请求交予backend php_server use_backend php_server if php_web # 如果满足策略php_web时,就将请求交予backend php_server use_backend static_server if static_web # 如果满足策略static_web时,就将请求交予backend static_server backend php_server #定义一个名为php_server的后端部分,frontend定义的请求会到到这里处理 mode http # 设置为http模式 balance source # 设置haproxy的调度算法为源地址hash cookie SERVERID # 允许向cookie插入SERVERID,每台服务器的SERVERID可在下面使用cookie关键字定义 option httpchk GET /test/index.php # 开启对后端服务器的健康检测,通过GET /test/index.php来判断后端服务器的健康情况 server php_server_1 10.12.25.68:80 cookie 1 check inter 2000 rise 3 fall 3 weight 2 server php_server_2 10.12.25.72:80 cookie 2 check inter 2000 rise 3 fall 3 weight 1 server php_server_bak 10.12.25.79: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[cookie 1]、接受健康监测[check]、监测的间隔时长,单位毫秒[inter #2000]、监测正常多少次后被认为后端服务器是可用的[rise 3]、监测失败多少次后被认为后端 #服务器是不可用的[fall 3]、分发的权重[weight 2]、最为备份用的后端服务器,当正常的服 #务器全部都宕机后,才会启用备份服务器[backup] backend static_server mode http option httpchk GET /test/index.html server static_server_1 10.12.25.83:80 cookie 3 check inter 2000 rise 3 fall 3 官方配置: http://haproxy.1wt.eu/download/1.4/doc/configuration.txt |
2.安装配置
tar -zxvf haproxy-2.3.5.tar.gz make TARGET=linux-glibc PREFIX=/usr/local/haproxy make install TARGET=linux-glibc PREFIX=/usr/local/haproxy mkdir -p /usr/local/haproxy/{conf,log,errorfiles} touch /usr/local/haproxy/conf/haproxy.cfg vim /usr/local/haproxy/conf/haproxy.cfg
global daemon # 后台方式运行 nbproc 1 chroot /usr/local/haproxy pidfile haproxy.pid user haproxy group haproxy defaults mode tcp #默认的模式mode { tcp|http|health },tcp是4层,http是7层,health只会返回OK retries 2 #两次连接失败就认为是服务器不可用,也可以通过后面设置 option redispatch #当serverId对应的服务器挂掉后,强制定向到其他健康的服务器 option abortonclose #当服务器负载很高的时候,自动结束掉当前队列处理比较久的链接 maxconn 65530 #默认的最大连接数 timeout connect 5000ms #连接超时 timeout client 30000ms #客户端超时 timeout server 30000ms #服务器超时 #timeout check 2000 #=心跳检测超时 log 127.0.0.1 local3 info #[err warning info debug],日志文件的输出定向。产生的日志级别为local3. 系统中local1-7,用户自己定义 balance roundrobin # 采用轮询算法 ################# 配置################# listen delegate #这里是配置负载均衡,test1是名字,可以任意 bind 0.0.0.0:3307 #这里是监听的IP地址和端口,端口号可以在0-65535之间,要避免端口冲突 mode tcp #连接的协议,这里是tcp协议 #maxconn 4086 #log 127.0.0.1 local0 debug #option httplog ###日志类别,记载http日志 #option dontlognull ###不记录空连接产生的日志信息 option httpclose ###每次请求完毕后主动关闭http通道,haproxy不支持keep-alive retries 3 ###3次连接失败就认为服务器不可用,主要通过后面的check检查 server s1 192.168.1.166:3307 check #负载的MySQL实例1 server s2 192.168.1.166:3308 check #负载的MySQL实例2 可以有多个,往下排列即 ################# 系统状态配置################# listen haproxy_stats stats enable bind *:8082 mode http option httplog log global maxconn 10 stats refresh 30s stats uri /admin stats realm haproxy stats auth admin:admin stats hide-version stats admin if TRUE |
3.配置日志收集(详情见)
第一种方式
安装日志收集服务
yum install -y rsyslog vim /etc/rsyslog.d/haproxy.conf
$ModLoad imudp $UDPServerRun 514 if ($programname == 'haproxy' and $syslogseverity-text == 'info') then -/var/log/haproxy/haproxy-info.log &~ if ($programname == 'haproxy' and $syslogseverity-text == 'notice') then -/var/log/haproxy/haproxy-notice. log &~
需要配置启动文件输入,回环监控日志输出
global log 127.0.0.1:514 local0
第二种方式
vi /etc/rsyslog.conf(添加如下内容) 和配置文件中定义的名称保持一致 $ModLoad imudp |
vi /etc/sysconfig/rsyslog ####################################### 把SYSLOGD_OPTIONS=”-m 0″ 改成 SYSLOGD_OPTIONS=”-r -m 0″ ####################################### |
相关解释说明: -r:打开接受外来日志消息的功能,其监控514 UDP端口; -x:关闭自动解析对方日志服务器的FQDN信息,这能避免DNS不完整所带来的麻烦; -m:修改syslog的内部mark消息写入间隔时间(0为关闭),例如240为每隔240分钟写入一次”–MARK–“信息; -h:默认情况下,syslog不会发送从远端接受过来的消息到其他主机,而使用该选项,则把该开关打开,所有 接受到的信息都可根据syslog.conf中定义的@主机转发过去 |
systemctl restart rsyslog.service |
4.修改启动脚本,配置开机启动
# 将源码目录下的examples/haproxy.init复制到/etc/init.d/下 cp /home/haproxy/haproxy-2.3.5/examples/haproxy.init /etc/init.d/haproxy # 添加执行权限 chmod +x /etc/init.d/haproxy |
修改启动脚本,加入如下配置
vim /etc/init.d/haproxy |
# 修改调整Begin PIDFILE=/var/run/haproxy.pid |
修改后的内容如下:
#!/bin/sh # # chkconfig: - 85 15 # description: HA-Proxy is a TCP/HTTP reverse proxy which is particularly suited \ # for high availability environments. # processname: haproxy # config: /etc/haproxy/haproxy.cfg # pidfile: /var/run/haproxy.pid # Script Author: Simon Matter <simon.matter@invoca.ch> # Version: 2004060600 # Source function library. if [ -f /etc/init.d/functions ]; then . /etc/init.d/functions elif [ -f /etc/rc.d/init.d/functions ] ; then . /etc/rc.d/init.d/functions else exit 0 fi # Source networking configuration. . /etc/sysconfig/network # Check that networking is up. [ "${NETWORKING}" = "no" ] && exit 0 # This is our service name #BASENAME=`basename $0` #if [ -L $0 ]; then # BASENAME=`find $0 -name $BASENAME -printf %l` # BASENAME=`basename $BASENAME` #fi #BIN=/usr/sbin/$BASENAME #CFG=/etc/$BASENAME/$BASENAME.cfg #[ -f $CFG ] || exit 1 #PIDFILE=/var/run/$BASENAME.pid #LOCKFILE=/var/lock/subsys/$BASENAME # 修改调整Begin BASENAME="haproxy" BIN=/usr/local/haproxy/sbin/haproxy CFG=/usr/local/haproxy/conf/haproxy.cfg [ -f $CFG ] || exit 1 PIDFILE=/var/run/haproxy.pid LOCKFILE=/var/lock/subsys/$BASENAME # 修改调整END RETVAL=0 start() { quiet_check if [ $? -ne 0 ]; then echo "Errors found in configuration file, check it with '$BASENAME check'." return 1 fi echo -n "Starting $BASENAME: " daemon $BIN -D -f $CFG -p $PIDFILE RETVAL=$? echo [ $RETVAL -eq 0 ] && touch $LOCKFILE return $RETVAL } stop() { echo -n "Shutting down $BASENAME: " killproc $BASENAME -USR1 RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -f $LOCKFILE [ $RETVAL -eq 0 ] && rm -f $PIDFILE return $RETVAL } restart() { quiet_check if [ $? -ne 0 ]; then echo "Errors found in configuration file, check it with '$BASENAME check'." return 1 fi stop start } reload() { if ! [ -s $PIDFILE ]; then return 0 fi quiet_check if [ $? -ne 0 ]; then echo "Errors found in configuration file, check it with '$BASENAME check'." return 1 fi $BIN -D -f $CFG -p $PIDFILE -sf $(cat $PIDFILE) } check() { $BIN -c -q -V -f $CFG } quiet_check() { $BIN -c -q -f $CFG } rhstatus() { status $BASENAME } condrestart() { [ -e $LOCKFILE ] && restart || : } # See how we were called. case "$1" in start) start ;; stop) stop ;; restart) restart ;; reload) reload ;; condrestart) condrestart ;; status) rhstatus ;; check) check ;; *) echo $"Usage: $BASENAME {start|stop|restart|reload|condrestart|status|check}" exit 1 esac exit $?
# 添加service服务 chkconfig –add /etc/init.d/haproxy |
5.启动方式说明
5.1指定配置文件启动方式
/usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/conf/haproxy.cfg |
root@pc3357 haproxy]# ps -axu | grep haproxy root 18703 0.0 0.0 149592 5292 pts/0 T 09:52 0:00 vim /usr/local/haproxy/conf/haproxy.cfg root 34560 0.0 0.0 95480 1548 ? Ss 10:34 0:00 /usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/conf/haproxy.cfg root 34616 0.0 0.0 112824 980 pts/0 R+ 10:35 0:00 grep –color=auto haproxy |
查看配置代理的3307端口
netstat -antup | grep 3307 |
[root@pc3357 haproxy]# netstat -antup | grep 3307 tcp 0 0 0.0.0.0:3307 0.0.0.0:* LISTEN 34560/haproxy |
停止服务
killall haproxy |
5.2 启动方式二
/etc/init.d/haproxy start |
5.3 启动方式三
systemctl start haproxy |
[root@pc3357 haproxy]# systemctl start haproxy [root@pc3357 haproxy]# netstat -antup | grep 3307 tcp 0 0 0.0.0.0:3307 0.0.0.0:* LISTEN 37933/haproxy |
6.健康监测
1、通过监听端口进行健康检测
这种检测方式,haproxy只会去检查后端server的端口,并不能保证服务的真正可用。
listen http_proxy 0.0.0.0:80
mode http
cookie SERVERID
balance roundrobin
option httpchk
server web1 192.168.1.1:80 cookie server01 check
server web2 192.168.1.2:80 cookie server02 check inter 500 rise 1 fall 2
2、通过URI获取进行健康检测
这种检测方式,是用过去GET后端server的的web页面,基本上可以代表后端服务的可用性。
listen http_proxy 0.0.0.0:80
mode http
cookie SERVERID
balance roundrobin
option httpchk GET /index.html
server web1 192.168.1.1:80 cookie server01 check
server web2 192.168.1.2:80 cookie server02 check inter 500 rise 1 fall 2
3、通过request获取的头部信息进行匹配进行健康检测
这种检测方式,则是基于高级,精细的一些监测需求。通过对后端服务访问的头部信息进行匹配检测。
listen http_proxy 0.0.0.0:80
mode http
cookie SERVERID
balance roundrobin
option httpchk HEAD /index.jsp HTTP/1.1\r\nHost:\ www.xxx.com
server web1 192.168.1.1:80 cookie server01 check
server web2 192.168.1.2:80 cookie server02 check inter 500 rise 1 fall 2
7.haproxy实现持久连接
1 调度算法source
haroxy 将用户IP经过hash计算后 指定到固定的真实服务器上(类似于nginx 的IP hash 指令)
配置指令 balance source
2 cookie 识别
haproxy 将WEB服务端发送给客户端的cookie中插入(或添加加前缀)haproxy定义的后端的服务器COOKIE ID。
配置指令例举 cookie SESSION_COOKIE insert indirect nocache
3 session 识别
haproxy 将后端服务器产生的session和后端服务器标识存在haproxy中的一张表里。客户端请求时先查询这张表。然后根据session分配后端server。
配置指令:appsession <cookie> len <length> timeout <holdtime>
8.管理界面信息查看
http://192.168.32.200:8082/admin_stats |
用户名密码:admin/admin |
启动mysql服务查看S1,S2服务状态,查看haproxy日志
配置参数说明(以下为转载内容)
1.全局配置参数
全局配置参数设定haproxy进程运行环境,一般和操作系统指定的值有关,配置正确后一般都不会去修改。全局配置参数一般都有对应的命令行选项。
1.1.进程管理及安全相关的参数。
haproxy是单进程、事件驱动、非阻塞模型的调度器。虽然是单进程,但官方强烈建议不要设置为多进程,因为单进程可以处理很多个代理连接请求且性能极好(官方手册说30W个代理实例都能良好运行),设置为多进程反而有一些限制。
- chroot :修改haproxy工作目录至指定目录,可提升haproxy安全级别,但要确保必须为空且任何用户均不能有写权限;
- daemon:让haproxy以守护进程的方式工作于后台,等同于命令行的”-D”选项,当然,也可以在命令行中以”-db”选项将其禁用;(建议设置项)
- uid/user:以指定的UID或用户名身份运行haproxy进程;
- gid/group:以指定的GID或组名运行haproxy,建议使用专用于运行haproxy的GID,以免因权限问题带来风险;
- log:定义全局的syslog服务器,接收haproxy启动和停止的日志。最多可以定义两个;
log <address> <facility> [max level [min level]]
- log-send-hostname [string]:在日志的最前面记录本机主机名或string。远程发送到日志服务器时可由此知道是haproxy主机发送的。
- pidfile:等同于命令行的”-p”选项。使用服务启动脚本启动haproxy时建议不要设置该项,以保证脚本能正确获取pid文件。
- nbproc :指定启动的haproxy进程个数,只能用于守护进程模式的haproxy;默认只启动一个进程,一般只在单进程仅能打开少数文件描述符的场景中才使用多进程模式;(官方强烈建议不要设置该选项)
- ulimit-n:设定每进程能够打开的最大文件描述符数量,默认haproxy会自动进行计算,因此不推荐修改此选项;(不建议设置项)
- stats:和多进程haproxy有关,由于不建议使用多进程,所以也不建议设置此项。但建议设置为”stats socket”将套接字和本地文件进行绑定,如”stats socket /var/lib/haproxy/stats”。
- node:定义当前节点的名称,用于HA场景中多haproxy进程使用相同IP地址时分辨哪个node正处于使用状态;
1.2.性能调整相关的参数。
- maxconn :设定每haproxy进程所接受的最大并发连接数,当达到此限定连接数后将不再接受新的连接。该参数特指和客户端的连接数,不包括和服务端的连接。等同于命令行选项”-n”;”ulimit -n”就是根据此值进行自动调整的;
- maxpipes :haproxy在使用splice()在内核中零复制时,是使用pipe传递进行报文粘接重组的,此选项用于设定每进程所允许使用的最大pipe个数;每个pipe会打开两个文件描述符,因此”ulimit -n”自动计算时会按需调大此值;默认值为maxconn/4。调小时会影响一定的性能;
- noepoll:在Linux系统上禁用epoll机制;(不建议设置此项)
- nokqueue:在BSD系统上禁用kqueue机制;
- nopoll:禁用poll机制;
- nosplice:禁止在Linux套接字上使用内核tcp重组,这会导致更多的recv/send系统调用;(在内核版本2.6.28之后极度不建议设置此项)
- spread-checks <0..50, in percent>:在haproxy后端有着众多服务器的场景中,在精确的时间间隔后统一对众服务器进行健康状况检查可能会带来意外问题;此选项用于将其检查的时间间隔长度上增加或减小一定的随机时长;默认为0,官方建议设置为2到5之间。(建议设置项)
- tune.bufsize :设定buffer的大小,同样的内存条件下,较小的值可以让haproxy有能力接受更多的并发连接,较大的值可以让某些应用程序使用较大的cookie信息;默认为16384,可在编译时修改,不过强烈建议使用默认值;(不建议设置项)
- tune.chksize :设定检查缓冲区的大小,单位为字节;更大的值有助于在较大的页面中完成基于字符串或正则pattern的文本查找,但也会占用更多的系统资源;(不建议设置项)
- tune.maxaccept :设定haproxy进程内核调度运行时一次性可以接受的连接的个数,较大的值可以带来较大的吞吐率,默认在单进程模式下为100,多进程模式下为8,设定为-1可以禁止此限制;(不建议设置项)
- tune.maxpollevents :设定一次io复用时系统调用可以处理的事件最大数,默认值取决于OS;其值小于200时可节约带宽,但会略微增大网络延迟,而大于200时会降低延迟,但会稍稍增加网络带宽的占用量;(不建议设置项)
- tune.maxrewrite :设定为首部重写或追加而预留的缓冲空间,建议使用1024左右的大小;在需要使用更大的空间时,haproxy会自动增加其值;(不建议设置项)
- tune.rcvbuf.client :设定两端的recv_buff大小(haproxy和客户端建立tcp,和后端服务器建立tcp,共两端,因此有两个recv_buff和两个send_buff)。单位为字节;(强烈推荐使用默认值)
- tune.rcvbuf.server :(强烈推荐使用默认值)
- tune.sndbuf.client:设定两端的send_buff大小(强烈推荐使用默认值)
- tune.sndbuf.server:(强烈推荐使用默认值)
因此,抛去不建议设置的项后,global段的设置大致如下:这也是yum安装haproxy时默认提供的配置
global
daemon
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
stats socket /var/lib/haproxy/stats
注意上面配置了使用local2记录log,因此还需去rsyslogd的配置文件中添加该设备以及记录的日志位置。如下:
cat <<eof>>/etc/rsyslog.conf
local2.* /var/log/haproxy.log
eof
2. proxy配置段和常用配置选项
proxy配置部分是haproxy最重要的配置部分,包含下面四种配置段:
- defaults []:设置frontend/backend/listen配置段的默认值。
- frontend :配置监听客户端连接的套接字。
- backend :配置haproxy所代理的后端服务器组。
- listen :定义一个完整的前端和后端代理,但后端可以不定义。所以有时候等价于frontend+backend。它常用于绑定前后端1对1的情况。
所有代理的名称只能使用大写字母、小写字母、数字、-(中线)、_(下划线)、.(点号)和:(冒号)。此外,ACL名称会区分字母大小写。
目前,有两种主流的代理模式:tcp代理(即所谓的4层代理)和http代理(即所谓的7层代理)。在4层代理模式下,haproxy简单的在两端进行双向转发。在7层代理模式下,haproxy会对协议进行分析,可以根据协议来允许、阻塞、切换、增加、修改和移除request或response中的属性内容。
http事务模型相关设置
- (no) option http-keep-alive
启用或禁用客户端和服务端到haproxy之间的长连接。haproxy将处理所有请求和响应报文,请求完后haproxy两端的连接都处于空闲状态。由于和后端保持了连接,可以以最快的方式重用会话。 - (no) option http-server-close
启用或禁用在haproxy处理完第一次响应之后关闭haproxy到服务端之间长连接的功能,但客户端的长连接还保持,后续的每次请求都重新建立和后端的连接,每次响应后都关闭和后端的连接。启用该选项时,haproxy将会在转发给后端server的request数据包中添加一个”Connection:Close”标记,后端Server看到此标记就会在响应后关闭tcp连接。 - (no) option http-tunnel
启用或禁用在haproxy处理完第一次请求和响应后关闭haproxy两端长连接的功能。在1.0-1.5.21版本该项是默认项,但现在不建议使用,因为会产生一些问题。 - (no) option forceclose
启用或禁用传输完响应报文后关闭两端的连接。 - (no) option htthttpcloseose(废弃选项)
- (no) option http-pretend-keepalive
有些服务器会无视带有”Connection:Close”标记的请求,从而http-server-close的后端发送响应后不会关闭tcp连接。设置该选项时,haproxy在收到响应后会主动关闭和后端的连接。不建议设置该选项,因为绝大多数服务器都能正常工作并且有很好的调整能力。
一般来说,对于高速局域网络来说,如果后端响应的速度非常快(比如后端是静态服务器响应小文件、后端是静态缓存服务器),这时建立tcp连接的代价就比较大,维持空闲连接的优势会非常明显。如果后端是动态应用程序,响应给haproxy的速度相对较慢,维持空闲连接的代价非常大,完全可以先释放长连接以腾出资源,在需要连接的时候再建立新tcp连接。因此:
(1).后端是静态内容缓存服务器时,或者就是静态服务器时,首选使用http-keep-alive模式;
(2).后端是动态应用程序服务器时,首选使用http-server-close模式。
默认情况下,如果客户端请求根据调度算法被调度到另一台后端服务器时,http-keep-alive模式下和后端服务器的空闲连接会立即断开,并重新和被调度选中的后端服务器建立连接。可以使用”prefer-last-server”选项,使得haproxy先查看当前保持的空闲连接是否可用,如果可用,则继续使用该空闲连接,但是这样会影响调度性能。
frontend和backend都可以设置这些模式选项,如果它们交叉设置了,最终何种模式会生效?例如,frontend设置了http-keep-alive,而bakcend设置了http-server-close时,取何种模式?计算方式采用如下矩阵:keepalive优先级是最弱的,forceclose是优先级是最高的。
balance
balance <algorithm>
可用于default、listen、backend配置段。
指定代理时负载均衡算法,支持的算法有:
- roundrobin(默认):根据权重进行轮询,在服务器的处理时间保持均匀分布时,这是最平衡、最公平的算法。此算法是动态的,表示权重可以在haproxy运行时调整后端服务器的权重并生效;
- static-rr:基于权重进行轮询,与roundrobin类似,但是为静态方法,在haproxy运行时调整其服务器权重不会生效;
- leastconn:新的连接请求被派发至具有最少连接数目的后端服务器;在有着较长时间会话的场景中推荐使用此算法,如LDAP、SQL等,其并不太适用于较短会话的应用层协议,如HTTP;此算法是动态的,可以在运行时调整其权重;
- source:将请求的源地址进行hash运算,使得同一个客户端IP的请求始终被派发至某特定的服务器;但当服务器权重总数发生变化时,如某服务器宕机或添加了新的服务器,许多客户端的请求可能会被派发至与此前请求不同的服务器;类似于nginx的ip_hash,可用于负载均衡无cookie功能的基于TCP的协议。默认为静态;
- uri:对URI的左半部分(“?”标记之前的部分)进行hash运算,并除以服务器的总权重来计算派发至某匹配服务器;这可以使得对同一个URI的请求总是被派发至某特定的服务器,除非服务器的权重总数发生了变化;此算法常用于代理缓存以提高缓存的命中率;但此算法仅应用于提供http服务的后端服务器;默认为静态算法;缺点是后端server宕机会造成严重抖动,可以通过hash-type设置hash算法为一致性哈希解决。
- url_param:一般用于将同一用户ID转发至同一服务器的情况。在使用了basic认证时,url中的param一般都会使用user=XXX。使用该算法会对该参数进行hash运算,然后除以总权重以决定分配到哪台后端server。
- hdr(name):基于指定的请求首部名称进行调度。首部中指定名称相同的调度至同一服务器。一般使用”hdr(host)”根据请求首部中的host即目标主机来进行hash运算。使用use_domain_only选项可以基于域名来哈希,使得访问www.longshuai.com和web.longshuai.com的请求都调度至同一服务器。
- rdp-cookie
- rdp-cookie(name)
roundrobin和static-rr是有区别的,roundrobin是动态慢轮询,不用重启服务即可调整其权重,而static-rr必须重启服务修改的权重才生效。例如原有2台后端server,新添加一台后,roundrobin会从此时开始慢慢的将请求轮询至此新服务器,而static-rr由于需要重启,所以重启前新server不会被调度到,重启后新server和旧server平均调度。一般来说,考虑加权轮询的时候,roundrobin要比static-rr好。
一般可纳入考虑的算法有roundrobin/static-rr/leastconn/uri,其中leastconn算法用于代理ldap、mysql等长时间会话连接的情况,uri算法用于代理后端为缓存服务器的情况。
(1). 用于调度MySQL服务器,使用何种算法?答:leastconn
(2). 用于调度静态服务器组,使用何种算法?答:roundrobin
(3). 调度动态应用程序服务器组,使用何种算法?答:通常客户端需要和后端应用程序服务器保持联系,一般会使用cookie或者session来实现,但如果特殊情况下无法通过它们实现,则可以使用source作为最后”亲和性”手段。注意,使用source算法时,后端服务器数量一改变,就会导致大量的会话断开。
(4). 调度缓存服务器,使用何种算法?答:uri,且设置hash-type为一致性哈希算法。
hash-type
hash-type <method>
不能用于frontend区段
定义用于将hash码映射至后端服务器的方法;可用方法有map-based和consistent,一般情况推荐使用默认的map-based方法。
- map-based:hash表是一个包含了所有在线服务器的静态数组。其hash值将会非常平滑,会将权重考虑在列,但其为静态方法,对在线服务器的权重进行调整将不会生效,这意味着其不支持慢速启动。此外,挑选服务器是根据其在数组中的位置进行的,因此,当一台服务器宕机或添加了一台新的服务器时,大多数连接将会被重新派发至一个与此前不同的服务器上。对于缓存服务器的工作场景来说,此方法不适用。
- consistent:(一致性哈希算法)hash表是一个由各服务器填充而成的树状结构;基于hash键在hash树中查找相应的服务器时,最近的服务器将被选中。此方法是动态的,支持在运行时修改服务器权重,因此兼容慢速启动的特性。添加一个新的服务器时,仅会对一小部分请求产生影响,因此,适用于后端服务器为cache的场景。不过,此算法不甚平滑,派发至各服务器的请求未必能达到理想的均衡效果,因此,可能需要不时的调整服务器的权重以获得更好的均衡性。
bind
bind [<address>]:<port_range> [, ...]
bind [<address>]:<port_range> [, ...] interface <interface>
能用于frontend和listen段
用于定义一个或几个监听的套接字。
<address>
:可选项,可以为主机名、IPv4地址、IPv6地址或*;省略此选项、将其指定为*或0.0.0.0时,将监听当前系统的所有IPv4地址;<port_range>
:可以是一个特定的TCP端口,也可是一个端口范围(如5005-5010),代理服务器将通过指定的端口来接收客户端请求;注意,小于1024的端口需要有特定权限的用户才能使用;<interface>
:指定物理接口的名称;
例如:
bind :80,:443
bind 10.0.0.1:10080,10.0.0.1:10443
mode
指定haproxy实例运行模式。可为tcp、http。tcp为4层代理模式,不会对协议进行任何分析,只是单纯地转发数据包,如HTTPS/MYSQL等,http为7层代理模式。如果所有配置区段都没有设置mode,则默认为tcp模式。
log
log global
log <address> <facility> [<level> [<minlevel>]]
为每个实例启用事件和流量日志,因此可用于所有区段。每个实例最多可以指定两个log参数。配置方法和意义同前文全局配置参数的log。
如果使用log global,则表示从全局继承日志设置。另外,如果全局已经定义过两个log了,此处除引用global外还自定义了一个log,则此自定义的log失效,因为只支持两个日志设置。
capture request header和capture response header
capture request header <name> len <length>
capture response header <name> len <length>
仅能用于"frontend"和"listen"区段
捕获并记录最近一次出现的指定请求首部或响应首部。请求首部是从客户端发起的请求首部,响应首部是从后端server响应并在haproxy准备发送给客户端前捕获的。捕获的首部值使用大括号{}
括起来后会添加进日志中。如果需要捕获多个首部值,它们将以指定的秩序出现在日志文件中,并以竖线”|”作为分隔符。不存在的首部记录为空字符串。
最常需要捕获的请求首部包括:在虚拟主机环境中使用的”Host”、上传请求首部中的”Content-length”、快速区别真实用户和网络机器人的”User-agent”,以及代理环境中记录请求真实来源的”X-Forward-For”。
一般需要捕获的响应首部为:记录还有多少内容需要接收的”Content-length”、跟踪重定向路径的”Location”。
<name>
:要捕获的首部的名称,此名称不区分字符大小写,但建议与它们出现在首部中的格式相同,比如大写首字母。需要注意的是,记录在日志中的是首部对应的值,而非首部名称。<length>
:指定记录首部值时所记录的精确长度,超出的部分将会被忽略。
可以捕获的请求首部的个数没有限制,但每个捕获最多只能记录64个字符。为了保证同一个frontend中日志格式的统一性,首部捕获仅能在frontend中定义。
例如:
capture request header Host len 15
capture request header X-Forwarded-For len 15
capture request header Referer len 15
capture response header Content-length len 9
capture response header Location len 15
maxconn
maxconn <conns>
不能用于backend区段
设定一个前端的最大并发连接数。对于大型站点来说,可以尽可能提高此值以便让haproxy管理连接队列,从而避免无法应答用户请求。当然,此最大值不能超出”global”段中的定义。此外,haproxy会为每个连接维持两个缓冲,每个缓冲的大小为16KB,再加上其它的数据,每个连接将大约占用33KB的RAM空间。这意味着经过适当优化后,有着1GB的可用RAM空间时将能维护20000-25000并发连接。
如果为指定了一个过大值,极端场景下,其最终占据的空间可能会超出当前主机的可用内存,这可能会带来意想不到的结果;因此,将其设定了一个可接受值方为明智决定。默认为2000。
use_backend
use_backend <backend> [{if | unless} <condition>]
定义当满足或不满足什么条件时使用哪个backend。条件判断是可选的,并且condition是基于acl的条件。
default_backend
default_backend <backend>
不可应用于backend区段。
在没有匹配的”use_backend”规则时为实例指定默认后端。在”frontend”和”backend”之间进行内容交换时,通常使用”use-backend”定义匹配规则;而没有被规则匹配到的请求将由此参数指定的后端接收。
例如,已有两组backend,名称分别为dynamic和static,当不匹配use_backend时将默认使用dynamic作为转发后端。
use_backend dynamic if url_dyn
use_backend static if url_css url_img extension_img
default_backend dynamic
server和default-server
server <name> <address>[:port] [param*]
声明后端server,因此不能用于defaults和frontend区段。
default-server [param*]
指定server的默认参数值,不能用于frontend区段
–<name>
:为此服务器指定的内部名称,将出现在日志及警告信息中;
<address>
:此服务器的IPv4地址,也支持使用可解析的主机名;[:port]
:haproxy将请求转发至后端服务器的哪个端口,为可选项;未设定时,将使用客户端请求时的同一端口;[param*]
:为此服务器设定的一系列参数;可用的参数非常多,下面是几个常用的参数;
服务器或默认服务器参数:
backup
:设定为备用服务器,当其它所有后端server均不可用时将启用此server;disabled
:禁用此后端服务器。check
:启动对此server执行健康状态检查,但需要配合定义在backend的具体检查方法(如httpcheck,mysql-check)才会进行指定的检查方式,不指定检查方法时将默认以tcp方式检查。check可以借助于额外的参数完成更精细的设定,如:inter <delay>
:设定健康状态检查的时间间隔,单位为毫秒,默认为2000;rise <count>
:设定server从离线状态重新上线需要成功检查的次数;不指定默认为2,一般可设置为1。fall <count>
:确认server从正常状态转换为不可用状态需要检查的次数;默认为3。
cookie <value>
:为指定server设定cookie值,指定的值将在请求入站时被检查,第一次为此值挑选的server将在后续的请求中被选中,其目的在于实现基于客户端cookie的持久连接;maxconn <maxconn>
:指定此后端服务器接受的最大并发连接数(不同于全局设置的maxconn,全局的maxconn是面向客户端的);如果发往此服务器的连接数高于指定的值,将被放于请求队列以等待其它连接释放;maxqueue <maxqueue>
:设定请求队列的最大长度;observe <mode>
:通过观察服务器的通信状况来判定其健康状态,默认禁用,支持的类型有”layer4″和”layer7″,layer4表示检查tcp连接是否正常,layer7仅用于http代理场景,通过后端server发送的response来判断,例如可以判断状态码,响应报文头部是否无法解析等;redir <prefix>
:启用重定向功能,将发往此服务器的GET和HEAD请求均以302状态码响应,意味着不会将请求转发至后端服务器;在prefix后面不能使用/,且不能使用相对地址;例如:server srv1 192.168.1.1:80 redir http://image1.mydomain.com check
weight <weight>
:权重,默认为1,最大值为256,0表示不参与负载均衡,即认为下线了不进行调度;
关于maxconn和maxqueue,这两个值都是此后端服务器的值。它们的大小和全局定义的maxconn是有一定大小比较关系的。如果没有定义maxqueue,则全局maxconn应该小于或等于后端所有服务器的maxconn之和,如果定义了maxqueue,则需要小于或等于后端所有服务器的maxconn和maxqueue之和。否则haproxy接收进来的请求超过后端服务器的压力极限,可能压垮后端。
例如:
server first 10.1.1.1:1080 cookie first check inter 1000
server second 10.1.1.2:1080 cookie second check inter 1000
server backup "${SRV_BACKUP}:1080" backup
server www1_dc1 "${LAN_DC1}.101:80"
server www1_dc2 "${LAN_DC2}.101:80"
default-server inter 1000 weight 13
option httpchk
option httpchk
option httpchk <uri>
option httpchk <method> <uri>
option httpchk <method> <uri> <version>
不能用于frontend段。
此指令表示基于http协议来做健康状况检查,只有返回状态码为2xx或3xx的才认为是健康的,其余所有状态码都认为不健康。不设置该选项时,默认采用tcp做健康检查,只要能建立tcp就表示健康。
uri
:检查的uri路径,默认为”/”。接受带有查询参数的urimethod
:http检查时使用的METHOD。不指定时默认为”OPTIONS”方法,也建议采用此方法,因为该请求方法对服务器造成的资源损耗最小。version
:检查的http协议版本,默认为http/1.0,但现在很多都采用HTTP/1.1,因此此处检查版本需要修改为HTTP/1.1,但对于该版本的HTTP协议来说,还强制要求指定Host,中间使用\r\n
隔离。
例如下面的配置,会将健康检查时的页面请求发送至后端192.168.1.1的80端口来确定该后端是正常的,但客户端的请求将转发至该后端的443端口。
backend https_relay
mode tcp
option httpchk
option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www
server apache1 192.168.1.1:443 check port 80
stats相关
stats enable
:启用基于程序编译时默认设置的统计报告,不能用于”frontend”区段。
只要没有另外的其它设定,默认就会使用如下的配置:
- stats uri : /haproxy?stats
- stats realm : "HAProxy Statistics"
- stats auth : no authentication
- stats scope : no restriction
尽管”stats enable”一条就能够启用统计报告,但还是建议设定其它所有的参数,以免依赖于默认设定而带来非预期后果。
例如:
backend public_www
server websrv1 172.16.100.11:80
stats enable
stats hide-version
stats scope .
stats uri /haproxyadmin?stats
stats realm Haproxy\ Statistics
stats auth statsadmin:password
stats auth statsmaster:password
stats hide-version
:启用统计报告并隐藏HAProxy版本报告,不能用于”frontend”区段。stats realm
:stats auth身份认证时的提示信息。设置的提示信息中,如果有空白字符,则需要转义。仅在与”stats auth”配合使用时有意义。stats auth
:启用带认证的统计报告功能并授权一个用户帐号和对应的密码(明文)。也就是说,想要查看统计报告需要提供身份和密码。不能用于”frontend”区段。stats admin
:满足指定条件时启用统计报告页面的管理功能,它允许通过web接口启用或禁用后端服务器。stats admin { if | unless } <cond>
下面是两个案例,第一个限制了仅能在本机打开报告页面时启用管理功能,第二个定义了仅允许通过认证的用户使用管理功能。
backend stats_localhost
stats enable
stats admin if LOCALHOST
backend stats_auth
stats enable
stats auth haproxyadmin:password
stats admin if TRUE
option forwardfor
option forwardfor [ except <network> ] [ header <name> ] [ if-none ]
允许在发往服务器的请求首部中插入”X-Forwarded-For”首部。
except <network>
:可选参数,当指定时表示请求中的源地址能匹配此网络时禁用此功能。header <name>
:可选参数,自定义首部名,如”X-Client”来替代”X-Forwarded-For”。有些独特的web服务器的确需要一个独特的首部。if-none
:仅在此首部不存在时才将其添加至请求报文问道中。
HAProxy工作于反向代理模式,其发往服务器的请求中的客户端IP均为HAProxy主机的地址而非真正客户端的地址,这会使得服务器端的日志信息记录不了真正的请求来源,”X-Forwarded-For”首部则可用于解决此问题。HAProxy可以向每个发往服务器的请求上添加此首部,并以客户端IP为其value。
下面是一个例子。
frontend www
mode http
option forwardfor except 127.0.0.1
错误页面相关
- errorfile
errorfile <code> <file>
在用户请求不存在的页面时,返回一个页面文件给客户端而非由haproxy生成的错误代码;可用于所有段中。
<code>
:指定对HTTP的哪些状态码返回指定的页面;这里可用的状态码有200、400、403、408、500、502、503和504;<file>
:指定用于响应的页面文件;
例如:errorfile 400 /etc/haproxy/errorpages/400badreq.http errorfile 403 /etc/haproxy/errorpages/403forbid.http errorfile 503 /etc/haproxy/errorpages/503sorry.http
- errorloc和errorloc302
errorloc <code> <url> errorloc302 <code> <url>
请求错误时,返回一个HTTP重定向至某URL的信息;可用于所有配置段中。
<code>
:指定对HTTP的哪些状态码返回指定的页面;这里可用的状态码有200、400、403、408、500、502、503和504;<url>
:Location首部中指定的页面位置的具体路径,可以是在当前服务器上的页面的相对路径,也可以使用绝对路径;需另外,这两个关键字都会返回302状态吗,这将使得客户端使用同样的HTTP方法获取指定的URL,对于非GET方法的场景(如POST)来说会产生问题,因为返回客户端的URL是不允许使用GET以外的其它方法的。如果的确有这种问题,可以使用errorloc303来返回303状态码给客户端。
- errorloc303
errorloc303 <code> <url>
请求错误时,返回一个HTTP重定向至某URL的信息给客户端;可用于所有配置段中。
<code>
:指定对HTTP的哪些状态码返回指定的页面;这里可用的状态码有400、403、408、500、502、503和504;<url>
:Location首部中指定的页面位置的具体路径,可以是在当前服务器上的页面的相对路径,也可以使用绝对路径;需要注意的是,如果URI自身错误时产生某特定状态码信息的话,有可能会导致循环定向;
例如:
backend webserver
server 172.16.100.6 172.16.100.6:80 check maxconn 3000 cookie srv01
server 172.16.100.7 172.16.100.7:80 check maxconn 3000 cookie srv02
errorloc 403 /etc/haproxy/errorpages/sorry.htm
errorloc 503 /etc/haproxy/errorpages/sorry.htm
在backend服务器组启用cookie功能,以便实现cookie绑定。需要同时设置server指令中的cookie选项。
后端为静态服务器设置:
cookie NAME insert nocache
PHP做后端时设置:
cookie SESSION_COOKIE insert indirect nocache
当客户端绑定cookie对应的后端服务器宕机后,应该为此客户端重新调度一个后端server,否则将打不开页面。这时需要使用option redispatch,表示当找不到cookie对应的服务器时分配新的服务器给客户端。
reqadd和rspadd
reqadd <string> [{if | unless} <cond>]
rspadd <string> [{if | unless} <cond>]
满足条件时向请求首部或响应首部的尾端添加自定义的字段。条件可选,当不给定条件时表示所有的请求首部或响应首部尾端都添加字段。
其中string包含了字段名和字段值,当然,既然是自定义,值肯定是可以省略的。注意,空白字符需要转义。
例如:
acl is-ssl dst_port 443
reqadd X-Proto:\ SSL if is-ssl
超时时间相关
时间单位默认都是毫秒。
- timeout http-request
haproxy等待客户端请求发送完整的超时时长。如果一开始发送了一部分,后续没有再发送,或者后续发送的一直是请求的某一部分,等达到超时时间将断开此连接。这可以防止DoS攻击。 - timeout queue
当调度的后端服务器已经满负载了,即达到了该backend的最大并发连接数时,后续要调度到此backend的请求将进入队列等待后端服务器释放可用。该超时时间设置的就是某一请求在队列中的最大等待时长,当达到此时长后将被认为该请求永远无法到达服务端,haproxy会丢弃该请求并向客户端返回503状态码。 - timeout connect 和retries
haproxy要和后端服务器建立连接时等待超时时间。一般如果haproxy和后端服务器处于局域网中,建立连接是瞬间的,所以该值可以设置的小一些。
retries表示和服务端建立连接失败时重试连接的次数。
注意:在健康检查时,将取timeout connect和inter的较小者作为检查时建立tcp连接的超时时间。 - timeout client
客户端和haproxy之间非活动连接保持的最大时长,达到此时长haproxy将断开和此客户端的连接。非活动表示客户端没有请求报文发送给haproxy。 - timeout server
服务端和haproxy之间非活动连接保持的最大时长,达到此时长haproxy将断开和此服务器的连接。非活动表示服务端没有响应报文发送给haproxy。 - timeout http-keep-alive
等待出现http请求报文出现的最大时长,即和客户端保持长连接的时长。建议设置小一些,以尽快释放连接,例如设置为2-3秒钟。
如果此项未设置,则使用timeout http-request值,如果timeout http-request也没设置,则使用timeout client的值。 - timeout check
在和服务端建立连接后,健康状况检查判断的超时时长(意思是,在建立TCP连接后,后端节点需要响应消息给haproxy,响应的消息可能是(1)httpcheck方式时,经过hash计算的http页面(2)tcp检查方式时的回复消息。如果haproxy隔了一段时间,都没有接收完这些消息,就认为这次检查不健康。因此timeout check是read回应消息的超时时长。而min(“timeout connect”,”inter”)则是建立tcp连接的超时时间,它们之和才是一次不健康检查的总时间)。
http协议过滤:http-request
http-request {allow | auth [realm <realm>] | redirect <rule> | deny [deny_status <status>]} [{if | unless} <condition>]
做7层http协议过滤。当http协议相关项满足条件时执行一个action,可以执行的action非常多,此处只列出了几项。
allow
:表示接受该http请求。auth
:表示提示输入用户认证信息,指定realm时将给出提示信息。redirect
:重定向功能。deny
:表示拒绝该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
tcp请求和响应过滤
tcp-request content <action> [{if | unless} <condition>]
tcp-response content <action> [{if | unless} <condition>]
做4层协议过滤。当满足条件时,haproxy对tcp请求或响应报文执行某个action。
对于request而言,只能用于listen和frontend。常用的action是accept和reject,表示满足条件时haproxy接受或拒绝该请求报文。
对于response而言,只能用于listen和backend。常用的action是accept、reject和close,前两者表示满足条件时接受或拒绝该响应报文,close表示满足条件时立即关闭和服务端的连接。
3. ACL
3.1 ACL语法
acl <aclname> <criterion> [flags] [operator] [<value>] ...
aclname:指定acl的名称,在引用时区分大小写。可随意指定,且多个acl指令可以指定同一个aclname,这表示"或"的逻辑关系。
flags:可选项,表示标识位。一般会用到的标识位只有"-i",表示不区分大小写。
operator:可选项,某些操作符,有"eq"、"ge"、"gt"、"le"、"lt",表示数学上的等于、大于、小于。
<criterion>:指定检查标准,即检查方法。见下文给出的常用4层标准和7层标准
value:根据criterion的不同,值的类型不同。
(1).4层常用检查标准,官方手册:https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#7.3.3
src <ip_addr>
src_port <PORT or PORT_ranges>
dst <ip_addr>
dst_port <PORT or PORT_ranges>
其中src、src_port、dst和dst_port就是检查标准creiterion,其后的值就是value。
例如:
acl accept_clients src 192.168.100.0/24
acl reject_clients src 172.16.0.0/16
tcp-request content accept if accept_clients
tcp-request content reject if reject_clients
tcp-request content reject # 此项表明不匹配前两项的默认都拒绝
(2).7层常用检查标准,官方手册:https://cbonte.github.io/haproxy-dconv/1.9/configuration.html#7.3.6
- hdr(HEADER):检查首部字段的值是否为指定的值,如
hdr(Connection) -i close
表示首部字段Connection的值是否为不区分大小写的close。hdr(Host) -i www.longshuai.com
表示首部字段Host的值是否为www.longshuai.com
,即请求的主机是否是指定的值。 - hdr_reg(HEADER):检查首部字段是否匹配指定的模式。如
hdr_reg(Host) -i .*\.longshuai\.com
。 - http_first_req:当正处理的请求是第一个请求时返回true。
- method:请求的方法为指定的方法时返回方法对应的数值,也就表示true。例如”method GET”。
acl valid_method method GET http-request deny if ! valid_method
- path:匹配uri的path部分,一般用来匹配精确的文件资源。例如
path -i /a.png
。 - path_beg:匹配path的前缀部分。
- path_end:匹配path的后缀部分。
- path_reg:使用正则表达式来匹配path。
- url:对整个url进行匹配。
- url_beg:对url的前缀进行匹配。
还有很多很多检查方法,更多的查询官方手册,太多了。一般4层的检查标准和7层对路径path和首部hdr的标准就够了。
多个条件使用”AND”、”OR”、”!”操作符表示逻辑与、逻辑或和取反,不写时默认的操作符是”AND”。
3.2 ACL实现动静分离示例
acl url_static path_beg /static /images /img /css /viedo /download # 定义静态检查标准
acl url_static path_end .gif .png .jpg .css .js .bmp # 定义静态检查标准
acl host_www path /index.html # 为主页专门定制acl
acl url_dynamic path_end .php .php5 # 定义动态检查标准
acl host_www hdr_beg(Host) -i www.longshuai.com # 定位到主页
use_backend static if url_static
use_backend dynamic if url_dynamic
use_backend www if host_www