HAProxy的配置文件为/etc/haproxy/haproxy.cfg
配置文件结构
- global:全局配置段
- 进程及安全配置相关的参数
- 性能调整相关参数
- Debug参数
- proxies:代理配置段
- defaults:为frontend, listen, backend提供默认配置
- fronted:描述了一组接受客户端连接的侦听套接字
- backend:代理将连接到的一组服务器以转发传入连接
- listen:定义一个完整的代理,其前端和后端部分组合在一个部分中
global常用配置项
进程及安全配置相关的参数
- chroot :将当前目录更改为并在之前执行chroot(),如果HAProxy被攻破了,也只能得到一个假的根环境,安全方面的设置
- deamon:运行在前台或者后台
- user:运行HAProxy进程的用户
- group:运行HAProxy进程的组
- uid:运行HAProxy进程的uid
- gid:运行HAProxy进程的gid
- nbproc :要启动的haproxy的进程数量;默认为1个,推荐为1个
- ulimit-n :每个haproxy进程可打开的最大文件数;会自动计算一个最佳的数字,建议不修改
性能调整参数
虽然说是调整性能的参数,但是一般情况下没有特殊需求,不建议修改
- maxconn :设定每个haproxy进程所能接受的最大并发连接数;
- maxconnrate : 每个进程每秒种所能创建的最大连接数量;
- maxsessrate :每个进程每秒钟所能创建的最大数量
- maxsslconn : 设定每个进程所能接受的最大ssl并发连接数
- spread-checks <0…50, in percent> :如果后端主机太多,为了避免同一时刻检查的主机数量太多,这里可以错峰检查。也就是提前或者延后一段时间检查,最多设置不能超过总长的百分之50,比如检测总时长是2s,如果提前或延后超过1s,则上一次的检查和这一次检查很可能会重叠,这时候就会出问题。
proxies常用的配置项
负载均衡算法
- balance roundrobin 基于权重进行轮询,在服务器的处理时间保持均匀分布时 ,这是最平衡、最公平的算法。此算法是动态的,这表示某权重可以在运行时进行调整
- balance static-rr 基于权重进行轮询,与roundrobin类似,但是他是静态方法,在运行时调整期后端权重不会生效,不过,其在后端服务器连接数上没有限制
- balance leastconn 最少连接者先处理,在有这较长会话的场景中推荐使用此算法,如LDAP、SQL等。其并不太适合用于较短会话的应用层协议,如HTTP,此算法是动态的,可以在运行时调整其权重
- balance source 将请求的源地址进行hash运算,并有后端的服务器的权重总数相处后派发至某匹配的服务器,这可以使得同一个客户端IP的请求始终被派发至某特定的服务器,不过,当服务器权重总数发生变化时,如某服务器宕机或者添加新服务器,许多的请求可能会被派发至与此前请求不同的服务器,常用于负载均衡无cooki功能的基于TCP的协议,默认为动态,不过可以使用hash-type修改此特性
- balance uri 对URI的左半部分(“问号”标记之前的部分)或整个URI进行hash运算,并由服务器的总权重相除后派发至某匹配的服务器,这可以使得对同一个URI的请求总是派发至某个匹配的服务器,除非服务器的权重总数发生了变化,此算法常用于代理缓存或反向代理以提高缓存的命中率,需要注意的是,此算法仅应用于HTTP后端服务器场景,其默认为静态算法,不过可以使用hash-type修改此特性
- balance url_param 通过URL指定的参数在每个HTTP GET请求中将会被索引,如果过找到了指定的参数且其通过等于号“=”被赋予了一个值,那么此值将被执行hash运算并被服务器的总权重相除后派发至某个匹配的服务器,此算法可以通过追踪请求中的用户标识进而确保同一个用户的ID请求被发送同一个特定的服务器,除非服务器的总权重发生了变化;如果某请求中没有出现指定的参数或其没有有效值,则使用轮询算法对其响应请求进行调度,此算法默认为静态,不过可以使用hash-type修改此特性
hash-type 哈希算法
格式:hash-type <method> <function> <modifier>
method有:
- map-based:除权取余法,哈希数据结构是静态的数组
- consistent:一致性哈希,哈希数据结构是一个树
server后端主机选项
格式:
server <name> <address>[:[port]] [param*]
server <name> <address>[:port] [settings ...]
default-server [settings ...] :server的默认参数
<name>:服务器在haproxy上的内部名称;出现在日志及警告信息;
<address>:服务器地址,支持使用主机名;
[:[port]]:端口映射;省略时,表示同bind中绑定的端口;
[param*]:常用的参数如下
maxconn <maxconn>:当前server的最大并发连接数;
maxqueue <maxqueue>:队列的最大长度。maxconn满了,多余的请求就需要放在队列中。
backlog <backlog>:当前server的连接数达到上限后的后援队列长度;
backup:设定当前server为备用服务器;即sorry server
check:对当前server做健康状态检测;
addr :设置检测时使用的IP地址
port :设置端口进行健康检测;
inter <delay>:连续两次检测之间的时间间隔,默认为2000ms;
rise <count>:连续多少次检测结果为“成功”才标记服务器为可用;默认为2;
fall <count>:连续多少次检测结果为“失败”才标记服务器为不可用;默认为3;
注意:httpchk,"smtpchk", "mysql-check", "pgsql-check" and "ssl-hello-chk" 用于定义应用层检测方法;
cookie <value>:为当前server指定其cookie值,用于实现基于cookie的会话黏性;
disabled:标记为不可用;
on-error <mode>:后端服务器故障时的行动策略
- fastinter: force fastinter
- fail-check: 快速强制检测,还没到下一个检测周期,快速触发一次故障探测
- sudden-death:一次失败直接标记为down
- mark-down: 立即标记为down并强制down
redir <prefix>:将发往此server的所有GET和HEAD类的请求重定向至指定的URL;
weight <weight>:权重,默认为1;
示例:
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 backend1 172.54.0.3:80 check weight 1 inter 2000 rise 1 fall 2 maxconn 1000
server backup ${SRV_BACKUP}:1080 backup
mode haproxy工作模式
- tcp:实例运行于纯TCP模式,在客户端和服务器端之间将建立一个全双工的连接,且不会对7层报文做任何类型的检查;此为默认模式,通常用于SSL、SSH、SMTP等应用
- http:实例运行于HTTP模式,客户端请求在转发至后端服务器之前将被深度分析,所有不与RFC格式兼容的请求都会被拒绝
- health:工作为健康状态检查的响应模式,当连接请求到达时回应“OK”后即断开连接;
格式:mode { tcp|http|health }
代理ssh示例:
listen ssh
bind :22022
balance roundrobin
mode tcp
server sshsrv1 192.168.253.158:22 check
server sshsrv1 192.168.253.128:22 check
代理http示例
listen web
bind :80
balance roundrobin
mode http
server sshsrv1 192.168.253.158:80 check
HTTP相关
cookie
用户访问服务器,haproxy转发到后端服务器。这时候由haproxy返回给用户的时候,可以操作报文首部,我们可以打个标记在cookie字段插入一个键值对。键为cookie的name,值为后端服务器设置的cookie名,从而做到session sticky。
格式:cookie <name> [ rewrite | insert | prefix ] [ indirect ] [ nocache ] [ postonly ] [ preserve ] [ httponly ] [ secure ] [ domain <domain> ]* [ maxidle <idle> ] [ maxlife <life> ]
<name>:自定义名称作为键
rewirte:重写;将已有的cookie重写
insert:插入;
prefix:前缀;
基于cookie的session sticky的实现:
backend websrvs
cookie WEBSRV insert nocache indirect #仅对nocache和indirect的情况下进行插入
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
option forwardfor
在由haproxy发往后端主机的请求报文中添加“X-Forwarded-For”首部,其值前端客户端的地址;用于向后端主发送真实的客户端IP
格式:option forwardfor [ except <network> ] [ header <name> ] [ if-none ]
[ except <network> ]:请求报请来自此处指定的网络时不予添加此首部;
[ header <name> ]:使用自定义的首部名称,而非“X-Forwarded-For”;
示例:
backend static
mode http
option forwardfor header X-Client
......
如果是nginx,自定义日志格式的时候需要写成$http_X_Client 来获取值,若为httpd,%{X-Client}i获取指定首部信息。
errorfile
返回设置的错误码的对应文件
errorfile <code> <file> 这里需要是文件路径
<code>:响应码,常用以下几个200, 400, 403, 408, 500, 502, 503, and 504.
<file>:响应的文件路径
示例:
errorfile 400 /etc/haproxy/errorfiles/400badreq.http
errorfile 408 /dev/null # workaround Chrome pre-connect bug
errorfile 403 /etc/haproxy/errorfiles/403forbid.http
errorfile 503 /etc/haproxy/errorfiles/503sorry.http
errorloc
errorfile返回一个本地文件,这里的errorloc类似重定向一个uri
格式:errorloc <code> <url>
示例:
errorloc 403 http://www.magedu.com/error_pages/403.html
reqadd
请求报文中添加首部
格式:reqadd <string> [{if | unless} <cond>]
rspadd
响应报文中添加首部
rspadd <string> [{if | unless} <cond>]
例子:
rspadd X-Via:\ HAPorxy
reqdel
删除请求报文首部
格式:reqdel <search> [{if | unless} <cond>]
rspdel
删除响应报文首部
格式:rspdel <search> [{if | unless} <cond>]
压缩相关参数
compression algo <algorithm> ...:启用http协议的压缩机制,指明压缩算法gzip, deflate;
compression type <mime type> ...:指明压缩的MIMI类型;
示例:
compression algo gzip
compression type text/html text/plain
对后端服务器做http协议的健康状态检测的常用配置项
格式:
option httpchk:定义基于http协议的7层健康状态检测机制
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 192.168.1.1:443 check port 80
连接超时时长常用配置项
timeout client <timeout>: 客户端一侧链接的非活动时长,默认单位是毫秒;
timeout server <timeout>:连接后端服务器一侧的非活动时长,如果时长足够长,就可以减少一些连接创建的开销。所以尽量长会好一些
timeout http-keep-alive <timeout>:持久连接的持久时长;
timeout http-request <timeout>:请求报文的超时时长,如果客户端一侧非常慢的发送,则服务器要维持这个连接就很浪费资源,这个就是请求报文的超时时长
timeout connect <timeout>:创建连接的超时时长。如果一直连接后端服务器不成功,
timeout client-fin <timeout>:客户端一侧非活动的半连接的超时时长
timeout server-fin <timeout>:服务端一侧非活动的半连接的超时时长
http-request
第7层请求的访问控制
格式:http-request { allow | deny } [ { if | unless } <condition> ]
示例:
http-request replace-value X-Forwarded-For ^192\.168\.(.*)$ 172.16.\1
报文首部为: X-Forwarded-For: 192.168.10.1, 192.168.13.24, 10.0.0.37
输出之后为: X-Forwarded-For: 172.16.10.1, 172.16.13.24, 10.0.0.37
日志相关设置
log
格式:log <address> [len <length>] <facility> [<level> [<minlevel>]]
haproxy默认没有记录日志的文件,需要依赖rsyslog收集,具体方法,首先在配置文件的global段添加一条配置项
log 127.0.0.1 local2
再修改/etc/rsyslog.conf
$ModLoad imudp #取消注释
$UDPServerRun 514 #取消注释
local2.* /var/log/haproxy.log #添加一行
然后重启
systemctl restart rsyslog haproxy
log-format :设置日志格式
格式:log-format <string>
示例:
log-format %{+Q}o\ %t\ %s\ %{-Q}r
统计接口相关参数
stats enable:启用统计页;基于默认的参数启用stats page;
stats auth <user>:<passwd>:认证时的账号和密码,可使用多次;默认不需要认证
stats realm <realm>:认证时的标题,提示;默认为 "HAProxy Statistics"
stats uri <prefix>:自定义stats page uri,访问的接口,默认 /haproxy?stats,
stats refresh <delay>:设定自动刷新时间间隔;
stats admin { if | unless } <cond>:启用stats page中的管理功能
stats hide-version 隐藏版本信息
配置示例:
listen stats
bind :9099
stats enable
stats uri /haproxy?admin
stats realm HAPorxy\ Stats\ Page
stats auth admin:haproxy
stats admin if TRUE
ACL相关
use_backend
当符合指定的条件时使用特定的backend
格式: use_backend <backend> [{if | unless} <condition>]
例子:
acl static path_beg -i /static /images /javascript /stylesheets
acl static path_end -i .jpg .gif .png .css .js .html
acl php path_end -i .php
use_backend static if static
use_backend dynamic if php
block
满足条件的情况下,阻止/放行第7层请求
格式:block { if | unless } <condition>
例子:
acl invalid_src src 0.0.0.0/7 224.0.0.0/3
acl invalid_src src_port 0:1023
acl local_dst hdr(host) -i localhost
block if invalid_src || local_dst
tcp-request connection
根据第4层条件对传入连接执行操作
格式:tcp-request connection {accept|reject} [{if | unless} <condition>]
示例:
mode tcp
acl invalid_src src 172.16.200.2
tcp-request connection reject if invalid_src
acl访问控制列表
格式:acl <aclname> <criterion> [flags] [operator] [<value>] ...
<aclname>:自定义的acl名,ACL名称必须由大写和小写字母,数字,' - '(短划线)组成,'_'(下划线),'.'(点)和':'(冒号)。ACL名称区分大小写
<value>的类型:
- 布尔值
- 整数
- IP address / network ip地址
- 字符串
- 正则表达式
- 16进制
<flags>
-i : 忽略字符大小写
-m : 使用特定的匹配方式(一般不用)
-n : 禁止dns主机名反解
-u : 每个acl必须使用独有的名称,默认可以重名,如果重名,表示的是或条件,满足其中一个即可
-- : 强行指名flag到哪结束,避免混淆
[operator]
匹配整数值:eq、ge、gt、le、lt
匹配字符串:不怎么用
- exact match (-m str) : 精确匹配
- substring match (-m sub) : 子串匹配
- prefix match (-m beg) :前缀匹配
- suffix match (-m end) : 后缀匹配
- subdir match (-m dir) : 子路径匹配
- domain match (-m dom) : 域名子串匹配
acl作为条件时的逻辑关系:
- AND (implicit)
- OR (explicit with the "or" keyword or the "||" operator)
- Negation with the exclamation mark ("!")
示例:
if invalid_src invalid_port
if invalid_src || invalid_port
if ! invalid_src invalid_port
<criterion> :
dst : ip
dst_port : 端口
src : ip
src_port : 端口
示例:
acl invalid_src src 172.16.200.2
path : string
path : exact string match 精确匹配,例如:/imgs/logos/logo.jpg
path_beg : prefix match 前缀匹配,例如: /imgs 表示/imgs下的所有内容都匹配
path_dir : subdir match 路径子串匹配
path_dom : domain match 域名子串匹配
path_end : suffix match 后缀匹配 ,例如:.jpg ;以.jpg结尾都匹配
path_len : length match 长度匹配
path_reg : regex match 正则匹配 ,例如:^/imgs/.*\.jpg 表示/imgs开头以.jpg结尾
path_sub : substring match 子串匹配 只要包含该子串就可以匹配到
下面的例子用于测试URL是否以/static、/images、/javascript或/stylesheets头。
acl url_static path_beg -i /static /images /javascript /stylesheets
例如,下面的例子用户测试URL是否以jpg、gif、png、css或js结尾。
acl url_static path_end -i .jpg .gif .png .css .js
url : string
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
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
下面的例子用于测试首部Connection的值是否为close。
hdr(Connection) -i close
下面的例子用记测试请求是否为提供静态内容的主机img、video、download或ftp。
acl host_static hdr_beg(host) -i img. video. download. ftp.
示例:
acl bad_curl hdr_sub(User-Agent) -i curl 拒绝curl访问
block if bad_curl
示例配置
动静分离
global
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
stats socket /var/lib/haproxy/stats
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
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
frontend webservs
bind *:788
acl static path_beg -i /static /images /javascript /stylesheets
acl static path_end -i .jpg .gif .png .css .js .html
acl php path_end -i .php
use_backend static if static
use_backend dynamic if php
default_backend dynamic
backend static
balance roundrobin
server sta1 192.168.253.128:6080 check maxconn 3000
server sta2 192.168.253.128:7080 check maxconn 3000
backend dynamic
balance source
server dyn 192.168.253.128:7080 check maxconn 1000
nginx+springboot+mysql+redis
global
daemon #以后台形式运行haproxy
chroot /usr/local/etc/haproxy #工作目录
#nbproc 1 #进程数量(可以设置多个进程提高性能)
#pidfile /var/run/haproxy.pid #haproxy的pid存放路径,启动进程的用户必须有权限访问此文件
defaults #默认配置,如果下面的frontend或者backend没配置,会采取这里的
log 127.0.0.1 local0 err #[err warning info debug]
#mode http #所处理的类别 (TCP4层,HTTP7层 )
retries 3 #3次连接失败就认为是服务器不可用,也可以通过后面设置
balance roundrobin #默认的负载均衡的方式,轮询方式
option redispatch #当serverId对应的服务器挂掉后,强制定向到其他健康的服务器
option abortonclose #当服务器负载很高的时候,自动结束掉当前队列处理比较久的链接
option dontlognull #日志中不记录负载均衡的心跳检测记录
option httplog #日志类别http日志格式
option forwardfor #如果后端服务器需要获得客户端真实ip需要配置的参数,可以从Http Header中获得客户端ip
maxconn 4096 #最大连接数
timeout connect 5000ms #连接超时
timeout client 30000ms #客户端超时
timeout server 30000ms #服务器超时
######## 监控界面配置 #################
listen admin_status
bind *:8888 # 监控界面访问信息
mode http
stats refresh 5s #统计页面刷新间隔
stats uri /haproxy # URI相对地址
stats realm Global\ statistics # 统计报告格式
stats auth admin:123456 # 登录账户信息
#######后端接口##############
frontend lkadmin_backend
bind *:8080
default_backend lkadmin_backends
backend lkadmin_backends
mode http
option httpchk GET /editor #http检查
balance static-rr
server backend1 172.54.0.3:80 check weight 1 inter 2000 rise 1 fall 2 maxconn 1000
#inter 2000 心跳检测间隔2000ms
#rise 1 检测1次正确表明服务器可用
#fall 2 检测2次错误表明服务器不可用
######前端页面##############
frontend lkadmin_frontend
bind *:80
log global
default_backend lkadmin_frontends
backend lkadmin_frontends
mode http
balance static-rr
option httpchk GET /
server frontend1 172.54.0.4:80 check weight 1 inter 2000 rise 1 fall 2 maxconn 1000
######## mysql###############
frontend mysql
bind *:3306
mode tcp
log global
option tcplog
default_backend mysql_servers
backend mysql_servers
balance leastconn #最少连接者先处理
# 在 mysql 创建一个没有权限的haproxy用户,密码为空。 haproxy用户
# create user 'haproxy'@'%' identified by ''; FLUSH PRIVILEGES;
option mysql-check user haproxy
server mysql_1 172.54.0.5:3306 check inter 2000 rise 1 fall 2 maxconn 300
#############redis######################
frontend redis
bind *:6379
mode tcp
log global
option tcplog
default_backend redis_servers
backend redis_servers
balance leastconn
server redis_1 172.54.0.6:6379 check inter 2000 rise 1 fall 2 maxconn 300
#########################################
大部分转载后调整: https://blog.csdn.net/l835311324/article/details/83031084