本文目录:
1.1 配置文件说明
1.2 简单配置示例
1.3 全局配置参数
1.4. proxy配置段和常用配置选项
1.4.1 http事务模型相关设置
1.4.2 balance
1.4.3 hash-type
1.4.4 bind
1.4.5 mode
1.4.6 log
1.4.7 capture request header 和 capture response header
1.4.8 maxconn
1.4.9 use_backend
1.4.10 default_backend
1.4.11 server和default-server
1.4.12 option httpcheck
1.4.13 stats相关
1.4.14 option forwardfor
1.4.15 错误页面相关
1.4.16 cookie和redispatch
1.4.17 reqadd和rspadd
1.4.18 超时时间相关
1.4.19 http协议过滤:http-request
1.4.20 tcp请求和响应过滤
1.5 ACL
1.5.1 ACL语法
1.5.2 ACL实现动静分离示例
haproxy几乎每个大版本都提供了官方手册(内容几乎都相同),手册非常详细。例如haproxy 1.7版本关于配置文件的官方手册:。
haproxy的灵魂在于配置文件,配置文件重点在于前端(frontend)和后端(backend)的定制。全局选项(global)的配置将默认提供的稍微修改下即可。
可以使用haproxy命令行检查配置文件语法是否正确。
haproxy -f /etc/haproxy/phaproxy.cfg -c
或者使用sysv脚本的check参数。
service haproxy check
HAProxy在启动之前会解析配置文件,有3处配置信息来源:
defaults
,listen
,frontend
和backend
段。另外haproxy配置文件引入了引号和转义符:反斜线表示转义符;单引号表示强引用;双引号表示弱引用。如果字符串内需要输入空格,则空格需要进行转义或者通过引号包围,不转义时在配置文件中表示分隔符。
如:
\ 标记一个空白字符以区分它的本义和用作分隔符时的空白符 \# to mark a hash and differentiate it from a comment \\ to use a backslash \' to use a single quote and differentiate it from strong quoting \" to use a double quote and differentiate it from weak quoting
下面几种情况是等价的:
log-format %{+Q}o\ %t\ %s\ %{-Q}r log-format "%{+Q}o %t %s %{-Q}r" log-format '%{+Q}o %t %s %{-Q}r' log-format "%{+Q}o %t"' %s %{-Q}r' log-format "%{+Q}o %t"' %s'\ %{-Q}r
在配置文件中,一些包含了数值的参数表示时间,如timeout。这些值默认以毫秒为单位,但也可以使用其它的时间单位后缀。
以下是一个简单的配置文件,该配置文件代理模式为http,frontend定义的是监听在前端所有网卡的80端口上,此文件中只定义了一个后端服务器组backend,该backend只包含一台监听在127.0.0.1:8000的服务器。在haproxy的术语中,frontend表示的是监听套接字,用于等待客户端的连接。
global daemon maxconn 256 defaults mode http timeout connect 5000ms timeout client 50000ms timeout server 50000ms frontend http-in bind *:80 default_backend web_servers backend web_servers server server1 127.0.0.1:8000 maxconn 32
如果使用listen配置方式替换backend和frontend,则更简单,以下是等价配置:
global daemon maxconn 256 defaults mode http timeout connect 5000ms timeout client 50000ms timeout server 50000ms listen http-in bind *:80 server server1 127.0.0.1:8000 maxconn 32
全局配置参数设定haproxy进程运行环境,一般和操作系统指定的值有关,配置正确后一般都不会去修改。全局配置参数一般都有对应的命令行选项。
1.进程管理及安全相关的参数。
haproxy是单进程、事件驱动、非阻塞模型的调度器。虽然是单进程,但官方强烈建议不要设置为多进程,因为单进程可以处理很多个代理连接请求且性能极好(官方手册说30W个代理实例都能良好运行),设置为多进程反而有一些限制。
log <address> <facility> [max level [min level]]
2.性能调整相关的参数。
因此,抛去不建议设置的项后,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
proxy配置部分是haproxy最重要的配置部分,包含下面四种配置段:
所有代理的名称只能使用大写字母、小写字母、数字、-(中线)、_(下划线)、.(点号)和:(冒号)。此外,ACL名称会区分字母大小写。
目前,有两种主流的代理模式:tcp代理(即所谓的4层代理)和http代理(即所谓的7层代理)。在4层代理模式下,haproxy简单的在两端进行双向转发。在7层代理模式下,haproxy会对协议进行分析,可以根据协议来允许、阻塞、切换、增加、修改和移除request或response中的属性内容。
一般来说,后端是静态内容缓存服务器时,或者就是静态服务器时,首选使用http-keep-alive模式,后端是动态应用程序服务器时,首选使用http-server-close模式。
默认情况下,如果客户端请求根据调度算法被调度到另一台后端服务器时,http-keep-alive模式下和后端服务器的空闲连接会立即断开,并重新和被调度选中的后端服务器建立连接。可以使用"prefer-last-server"选项,使得haproxy先查看当前保持的空闲连接是否可用,如果可用,则继续使用该空闲连接,但是这样会影响调度性能。
frontend和backend都可以设置这些模式选项,如果它们交叉设置了,最终何种模式会生效?例如,frontend设置了http-keep-alive,而bakcend设置了http-server-close时,取何种模式?计算方式采用如下矩阵:keepalive优先级是最弱的,forceclose是优先级是最高的。
balance <algorithm> 可用于default、listen、backend配置段。
指定代理时负载均衡算法,支持的算法有:
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). 调度动态应用程序服务器组,使用何种算法?答:使用source。可以使用cookie指令来替代该算法,因为cookie生效的优先级高于调度算法。
(4). 调度缓存服务器,使用何种算法?答:uri,且设置hash-type为一致性哈希算法。
hash-type <method> 不能用于frontend区段
定义用于将hash码映射至后端服务器的方法;可用方法有map-based和consistent,一般情况推荐使用默认的map-based方法。
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
指定haproxy实例运行模式。可为tcp、http。tcp为4层代理模式,不会对协议进行任何分析,只是单纯地转发数据包,如HTTPS/MYSQL等,http为7层代理模式。如果所有配置区段都没有设置mode,则默认为tcp模式。
log global log <address> <facility> [<level> [<minlevel>]]
为每个实例启用事件和流量日志,因此可用于所有区段。每个实例最多可以指定两个log参数。配置方法和意义同前文全局配置参数的log。
如果使用log global,则表示从全局继承日志设置。另外,如果全局已经定义过两个log了,此处除引用global外还自定义了一个log,则此自定义的log失效,因为只支持两个日志设置。
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 <conns> 不能用于backend区段
设定一个前端的最大并发连接数。对于大型站点来说,可以尽可能提高此值以便让haproxy管理连接队列,从而避免无法应答用户请求。当然,此最大值不能超出"global"段中的定义。此外,haproxy会为每个连接维持两个缓冲,每个缓冲的大小为8KB,再加上其它的数据,每个连接将大约占用17KB的RAM空间。这意味着经过适当优化后,有着1GB的可用RAM空间时将能维护40000-50000并发连接。
如果为指定了一个过大值,极端场景下,其最终占据的空间可能会超出当前主机的可用内存,这可能会带来意想不到的结果;因此,将其设定了一个可接受值方为明智决定。默认为2000。
use_backend <backend> [{if | unless} <condition>]
定义当满足或不满足什么条件时使用哪个backend。条件判断是可选的,并且condition是基于acl的条件。
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 <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 <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 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 [ 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 <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 <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 <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 <string> [{if | unless} <cond>] rspadd <string> [{if | unless} <cond>]
满足条件时向请求首部或响应首部的尾端添加自定义的字段。条件可选,当不给定条件时表示所有的请求首部或响应首部尾端都添加字段。
其中string包含了字段名和字段值,当然,既然是自定义,值肯定是可以省略的。注意,空白字符需要转义。
例如:
acl is-ssl dst_port 443 reqadd X-Proto:\ SSL if is-ssl
时间单位默认都是毫秒。
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-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表示满足条件时立即关闭和服务端的连接。
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(Connection) -i close
表示首部字段Connection的值是否为不区分大小写的close。hdr(Host) -i www.longshuai.com
表示首部字段Host的值是否为www.longshuai.com
,即请求的主机是否是指定的值。hdr_reg(Host) -i .*\.longshuai\.com
。acl valid_method method GET http-request deny if ! valid_method
path -i /a.png
。还有很多很多检查方法,更多的查询官方手册,太多了。一般4层的检查标准和7层对路径path和首部hdr的标准就够了。
多个条件使用"AND"、"OR"、"!"操作符表示逻辑与、逻辑或和取反,不写时默认的操作符是"AND"。
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 / # 为主页专门定制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
注:若您觉得这篇文章还不错请点击右下角推荐,您的支持能激发作者更大的写作热情,非常感谢!
如对本文有疑问, 点击进行留言回复!!
linux下文本编辑器vim的使用方法(复制、粘贴、替换、行号、撤销、多文件操作)
网友评论