HAProxy简介
HAProxy简介
HAProxy提供高可用性、负载均衡以及基于TCP和HTTP应用的代理,它是免费、开源、快速并且可靠的一种解决方案。
1 haproxy特点——引自散尽浮华的博客
1)HAProxy 也是支持虚拟主机的。
2)HAProxy 的优点能够补充 Nginx 的一些缺点,比如支持 Session 的保持,Cookie的引导;同时支持通过获取指定的 url 来检测后端服务器的状态。
3)HAProxy 跟 LVS 类似,本身就只是一款负载均衡软件;单纯从效率上来讲HAProxy 会比 Nginx 有更出色的负载均衡速度,在并发处理上也是优于 Nginx 的。
4)HAProxy 支持 TCP 协议的负载均衡转发,可以对 MySQL 读进行负载均衡,对后端的 MySQL 节点进行检测和负载均衡,大家可以用 LVS+Keepalived 对 MySQL主从做负载均衡。
5)HAProxy 负载均衡策略非常多, HAProxy 的负载均衡算法现在具体有如下8种:
1> roundrobin,表示简单的轮询,这个不多说,这个是负载均衡基本都具备的;
2> static-rr,表示根据权重,建议关注;
3> leastconn,表示最少连接者先处理,建议关注;
4> source,表示根据请求源 IP,这个跟 Nginx 的 IP_hash 机制类似,我们用其作为解决 session 问题的一种方法,建议关注;
5> ri,表示根据请求的 URI;
6> rl_param,表示根据请求的 URl 参数’balance url_param’ requires an URLparameter name;
7> hdr(name),表示根据 HTTP 请求头来锁定每一次 HTTP 请求;
8> rdp-cookie(name),表示根据据 cookie(name)来锁定并哈希每一次 TCP 请求。
2 配置文件参数简介
haproxy程序环境:
- 主程序:/usr/sbin/haproxy
- 主配置文件:/etc/haproxy/haproxy.cfg
- Unit file:/usr/lib/systemd/system/haproxy.service
- 官方文档:http://cbonte.github.io/haproxy-dconv/
2.1 global全局配置部分参数
-
进程及安全管理:
- chroot:限定工作目录提升安全性,注意的是要确保指定的目录为空目录且任何用户均不能有写权限;
- deamon:让haproxy以守护进程的方式工作于后台;
- user, group, uid, gid: 设定haproxy运行的用户及组等;
-
log:定义全局的syslog服务器;最多可以定义两个;
log
[len] [max level [min level]] 在代理配置段使用log global,则表示从全局继承日志设置。如果全局已经定义过两个log了,此处除引用global外还自定义了一个log,则此自定义的log失效,因为只支持两个日志设置。
-
nbproc
:要启动的haproxy的进程数量,官方建议单进程模式即1 ; -
ulimit-n
:每个haproxy进程可打开的最大文件数;不推荐手动指定,haproxy会自动调整 ; -
连接数相关:
- maxconn
:设定每个haproxy进程所能接受的最大并发连接数; - maxconnrate
:每个进程每秒种所能创建的最大tcp连接数量; - maxsessrate
:每秒能创建的最大会话数; - maxsslconn
:设置每个进程最大并发ssl连接数;
- maxconn
-
spread-checks <0..50, in percent> 单位百分比,有时, 需要避免以固定的时间间隔,发送代理和健康检查,否则会健康检测会过多的占用带宽。例如, 当许多逻辑服务器位于同一物理服务器上或者后端服务器数量很多的情况下。在这个参数的帮助下, 可以在检查间隔增加一些随机性时间介于0和 +/-50之间。默认值保持为0。
2.2 代理配置段
- “defaults”段用于为所有其它配置段提供默认参数;
- “frontend”段用于定义一系列监听的套接字,这些套接字可接受客户端请求并与之建立连接;
- “backend”段用于定义一系列“后端”服务器,代理将会将对应客户端的请求转发至这些服务器;
- “listen”段通过同时指定监听参数与后端服务器简要的定义了一个完整的代理;
所有代理的名称只能使用大写字母、小写字母、数字、-(中线)、_(下划线)、.(点号)和:(冒号)。此外,ACL名称会区分字母大小写。
-
部分常用参数,本段引自博客园——骏马金龙博客
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 forceclose
启用或禁用传输完响应报文后关闭两端的连接。一般来说,对于高速局域网络来说,如果后端响应的速度非常快(比如后端是静态服务器响应小文件、后端是静态缓存服务器),这时建立tcp连接的代价就比较大,维持空闲连接的优势会非常明显。如果后端是动态应用程序,响应给haproxy的速度相对较慢,维持空闲连接的代价非常大,完全可以先释放长连接以腾出资源,在需要连接的时候再建立新tcp连接。 因此:
(1).后端是静态内容缓存服务器时,或者就是静态服务器时,首选使用http-keep-alive模式;
(2).后端是动态应用程序服务器时,首选使用http-server-close模式。balance负载均衡调度算法
balance
可用于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算法为consistent一致性哈希解决。
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为一致性哈希算法。 -
server配置相关
-
server
[:[port]][param*]定义后端主机的各服务器及其选项不可用于defaults与frontend配置段;
-
default-server [settings ...]
指定server的默认值,不能用于frontend配置段;
-
:服务器在haproxy上的内部名称;出现在日志及警告信息; - :服务器地址,支持使用主机名;
-
[:[port]]:端口映射;省略时,表示同bind中绑定的端口;
-
[param*]:为此服务器设定的一系列参数
-
maxconn
:当前server的最大并发连接数; -
backlog
:当前server的连接数达到上限后的后援队列长度; -
backup:设定当前server为备用服务器;
-
check:对当前server做健康状态检测;
-
addr :检测时使用的IP地址;
-
port :针对此端口进行检测;
-
inter
:连续两次检测之间的时间间隔,默认为2000ms; -
rise
:连续多少次检测结果为“成功”才标记服务器为可用;默认为2; -
fall
:连续多少次检测结果为“失败”才标记服务器为不可用;默认为3; 注意:httpchk,"smtpchk", "mysql-check", "pgsql-check" and "ssl-hello-chk" 用于定义应用层检测方法;
-
cookie
:为当前server指定其cookie值,用于实现基于cookie的会话黏性; -
disabled:标记为不可用;
-
redir
:将发往此server的所有GET和HEAD类的请求重定向至指定的URL; -
weight
:权重,默认为1;
-
-
-
统计接口启用相关的参数:
-
stats enable : 启用统计页;基于默认的参数启用stats page;
-
stats uri : /haproxy?stats 定义状态页路径;
-
stats realm : "HAProxy Statistics" 认证领域名,即输入用户口令时的标题信息;
-
stats auth : no authentication 是否开启验证;
-
stats scope : no restriction
-
stats auth
: 认证时的账号和密码,可使用多次; -
stats realm
认证时的realm; -
stats uri
自定义stats page uri ; -
stats refresh
设定自动刷新时间间隔; -
stats admin { if | unless }
启用stats page中的管理功能 ; 配置示例:
listen stats bind :9099 stats enable stats realm HAPorxy\ Stats\ Page stats auth admin:admin stats admin if TRUE
-
-
基于cookie的session sticky的实现:
cookie
[ rewrite | insert | prefix ][ indirect ] [ nocache ]
常用组合:insert nocache indirect
-
:设定cookie名称 -
rewrite:重写cookie,不推荐使用;
-
insert: haproxy将报文发给客户端前,先插入一个cookie,cookie值由server项中cookie指定;
-
indirect: 以下3段均引用自骏马金龙博客https://www.cnblogs.com/f-ck-need-u/p/8553190.html#2-2-cookie-prefix
如果不配合"indirect"选项,服务端可以看到客户端请求时的所有cookie信息。如果配合"indirect"选项,则haproxy在将请求转发给后端时,将删除自己设置的cookie,使得后端只能看到它自己的cookie,这样对后端来说,整个过程是完全透明的,它不知道前面有负载均衡软件。
-
nocache
当客户端和HAProxy之间存在缓存时(如CDN),建议将insert配合nocache一起使用 ,因为nocache确保如果需要插入cookie,则可缓存页面将被标记为不可缓存。这一点很重要,因为如果所有cookie都添加到可缓存的页面上,则所有客户都将从中间的缓存层获取页面,并且将共享同一个Cookie,从而导致某台后端服务器接收的流量远远超过其他后端服务器。
-
prefix:
haproxy将在已存在的cookie(例如后端应用服务器设置的)上添加前缀cookie值,这个前缀部分是server指令中的cookie设置的,代表的是服务端标识符。在客户端再次访问时,haproxy将会自动移除这部分前缀,使得服务端只能看到它自己发出的cookie。在一些特殊环境下,客户端不支持多个"Set-Cookie"字段,这时可以使用prefix。
使用prefix的时候,cookie指令设置的cookie名必须和后端设置的cookie一样(在本文的环境中是PHPSESSID),否则prefix模式下的haproxy不会对响应报文做任何改变。
2.3 ACL
使用访问控制列表 (ACL) 提供了一种灵活的解决方案来进行访问流量控制, 通常是根据从请求、响应或任何环境状态提取的内容来做出决策。
2.3.1 ACL语法
acl
-
aclname : 指定ACL名称,区分大小写,可多条ACL同名,之间是或关系,value满足其一即是匹配。
-
criterion:指定检查标准:
-
如4层:src、src_port、dst、dst_port,
-
7层:
-
path : 精确匹配字符串,例如:path -i /1.txt
path_beg : 匹配 path的前缀部分
path_dir : 路径子集匹配
path_dom : 域名子集匹配
path_end : 后缀匹配
path_len : 长度匹配
path_reg : 模式匹配
path_sub : 字符串子集匹配
-
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
-
hdr([
[, ]]) : 精确匹配某首部最后一次出现的值 hdr_beg([
[, ]]) : prefix match hdr_dir([
[, ]]) : subdir match hdr_dom([
[, ]]) : domain match hdr_end([
[, ]]) : suffix match hdr_len([
[, ]]) : length match hdr_reg([
[, ]]) : regex match hdr_sub([
[, ]]) : substring match -
status : integer
Returns an integer containing the HTTP status code in the HTTP response.
-
-
-
flag:标志位,常用如-i 不区分大小写、-n禁止DNS解析。
3 动静分离配置示例
frontend web *:80
acl url_static path_beg -i /static /images /javascript /stylesheets
acl url_static path_end -i .jpg .gif .png .css .js .html .txt .htm
use_backend staticsrvs if url_static
default_backend appsrvs
backend staticsrvs
balance roundrobin
server stcsrv1 172.16.100.6:80 check
backend appsrvs
balance roundrobin
server app1 172.16.100.7:80 check
server app1 172.16.100.7:8080 check
listen stats
bind :9091
stats enable
stats auth admin:admin
stats admin if TRUE