- haproxy 高可用负载均衡
- haproxy 源码安装
- haproxy 配置参数
- haproxy 配置场景
- haproxy 调度算法
- haproxy ACL
1.0 源码安装
- 2台 haproxy 同样安装操作
1.1 部署环境
OS | VERSION | IP | ROLE |
---|---|---|---|
CentOS 7.9 | Haproxy 2.4.0 | 192.168.1.171 | haproxy |
192.168.1.172 | haproxy |
1.2 haproxy 依赖安装
1 | # yum -y install gcc readline-devel openssl-devel systemd-devel socat psmisc # 依赖安装 |
1.3 haproxy 下载
1 | # cd /data/apps/ |
1.4 haproxy 编译
1 | # tar -xf haproxy-2.4.0.tar.gz |
1.5 haproxy 配置
1 | # mkdir /data/apps/haproxy/conf |
1.6 haproxy 启动项
1 | # cat /usr/lib/systemd/system/haproxy.service |
1.7 haproxy 日志配置
1 | # mkdir /data/apps/haproxy/logs |
2.0 配置参数
- 2台 haproxy 同样安装操作
2.1 haproxy 配置示例
1 | # cat /data/apps/haproxy/conf/haproxy.cfg |
1 | haproxy: |
2.2 haproxy 配置参数
2.2.1 global 配置参数
1 | // Global settings 全局配置,用于设定全局配置参数 |
2.2.2 default 段参数
- defaults 段用于为所有其它配置段提供默认参数
2.2.2.1 option 参数
1 | // option httplog: 用来记录日志,其通常包含但不限于HTTP请求、连接计时器、会话状态、连接数、铺货的首部及cookie、"frontend"、"backend"等信息 |
2.2.2.2 timeout 参数
1 | // timeout queue 1m: 当请求超过最大并发连接数,多余请求会进入队列,那该请求在等待多长时间则超时 |
2.2.3 haproxy proxies 配置
2.2.3.1 mode 参数
1 | // mode 概念: 设置 haproxy 实例运行的协议 |
2.2.3.2 bind 参数
1 | // bind 概念: 设置haproxy实例运行的端口 |
2.2.3.3 maxconn 参数
1 | // maxconn 概念: 设定一个前端的最大并发连接数,对于大型站点来说,应该尽可能提高此值,从而避免haproxy无法应答用户请求。当然,此值最大值不能超出global段中的定义。 |
2.2.4 haproxy server 参数
- 为后端声明一个server节点信息。因此,不能用于defaults和frontend区段
- server 语法: server <name> <address>[:port] [param*]
- <name>: 为此服务器指定标识名称,会出现在日志文件中
- <address>: 填写节点的IPv4地址,也支持使用可解析的主机名称
- [:port]: 指定将连接所发往节点的目标端口,如未设定,则使用客户端请求的端口
- [param*]: 为此服务器设定的一系列参数;其可用的参数非常多,下面仅说明几个常用的参数
- backup: 在负载均衡场景中,所有的正常server均不可用时,此backup节点则会顶替提供服务
- check: 对此server进行TCP的健康状态检查
- inter DELAY: 设定健康状态检查的时间间隔,单位为毫秒,默认为2000毫秒
- rise COUNT: 设置离线状态转换至正常状态需要成功检查的次数
- fall COUNT: 设置正常状态节点转换为不可用状态,需要检查的次数
- maxconn MAXCONN: 指定此服务器接受的最大并发连接数
- maxqueue MAXQUEUE: 设定请求队列的最大长度
- weight WEIGHT: 服务器节点权重,默认为1,最大值为256。0表示不参与负载均衡
3.0 配置场景
3.1 haproxy 子配置管理
- 当业务众多时,所有配置将在”haproxy.cfg”一个配置文件中,维护起来非常麻烦。可将其拆分成不同的业务的子配置文件,从而方便维护。
1 | # cat /data/apps/haproxy/conf/haproxy.cfg |
1 | // 众多子配置文件可以以单独的的配置文件形式存在 |
1 | # cat /usr/lib/systemd/system/haproxy.service |
3.2 haproxy 状态检测配置
- haproxy 有统计报告功能,可以让使用者通过 web 页面概览后端服务器的概况,甚至更改它们的状态
1 | # cat /data/apps/haproxy/conf/conf.d/stats.ink8s.com.cfg |
3.3 haproxy 动态上线与下线
1 | # cat /data/apps/haproxy/conf/haproxy.cfg |
4.0 调度算法
- haproxy 根据后端服务器的负载,或其它的计算的标准,判断挑选哪台RS进行请求处理
- haproxy 调度算法语法,可用于 defaults、listen、backend
4.1 roundrobin
- roundrobin 基于权重进行轮询,保持均匀分布,这是最平衡、最公平的算法
- 此算法是动态的,这表示其权重可以在运行时进行调整,不过在设计上,每个后端服务器仅能最多接受4128个连接
1 | # cat app.ink8s.com.cfg |
4.1.1 动态调整
- 通过 socat 命令动态调整权重,将web01节点的权重调整为3
1 | # echo "get weight app_servers/web01" | socat stdio /data/apps/haproxy/stats # 查看 |
4.1.2 静态 static-rr
- static-rr 加权轮询调度算法,根据服务器的硬件情况、以及处理能力,为每台服务器分配不同的权值,使其能够接受相应权值的服务器请求
- 此算法是静态的,这表示其权重不可用在运行时进行调整
1 | # cat app.ink8s.com.cfg |
4.2 leastconn
- leastconn 新的连接请求被派发至具有最少连接数目的后端服务器
- 此算法是动态的,可以在运行时调整其权重
1 | # cat app.ink8s.com.cfg |
4.3 source
- source 源地址hash调度算法,将请求的源地址进行 hash 运算,得到一个具体的数值,同时对后端服务器进行编号,按照运算结果将请求分发到对应编号的服务器上
- 这可对不同源 IP 的访问进行负载分发,对同一客户端 IP 的请求始终被派发至某特定的服务器
- 注意: 如果服务器宕机或新添加了服务器,许多客户端的请求可能会被派发至于此前请求不同的服务器;不过也可以使用 hash-type 修改此特性
1 | # cat app.ink8s.com.cfg |
1 | # cat app.ink8s.com.cfg |
4.4 rui
- rui 基于对用户请求的 rui 做 hash 并将请求转发到后端指定服务器
- 理解: 同一个节点访问不同的 rui 可能会被调度到不同的后端服务器处理,但是不同的节点访问相同的 rui 则会被调度到同一台服务器处理,因为基于 rui 调度是在服务端完成的而非客户端,这种调度算法多用在缓存场景,能有效提高命中率
- 注意: 此算法仅应用于 HTTP 后端服务器场景;其默认为静态算法,不过也可以使用 hash-type 修改此特性
1 | # cat app.ink8s.com.cfg |
5.0 ACL
- ACL 主要对请求报文和响应报文进行匹配和过滤。其配置法则通常分为两步:
- 首先定义 ACL 规则,即定义一个测试条件,条件可以是请求报文中的源地址、源端口、目标地址、目标端口、请求方法、RUL、文件后缀等
- 然后再条件得到满足时执行相应的动作;比如阻止请求、又或者转发请求至某特定的后端
5.1 ACL 定义方法
1 | // ACL 语法 |
ACL 名称,可使用字母 数字 : . - _ 区分字符大小写 - <criterion> 比较的标准和条件
- [:port]: 指定将连接所发往节点的目标端口,如未设定,则使用客户端请求的端口
- [param*]: 为此服务器设定的一系列参数;其可用的参数非常多,下面仅说明几个常用的参数
- <flags> 条件标记
- -i 不区分大小写
- -m 使用 pattern 匹配方法
- -n 不做 DNS 解析
- -u 禁止 acl 重名,否则多个同名的 ACL 为或的关系
- [operator] 条件筛选
- -eq、-ne、-ge、le、gt、lt
- (-m str) 字符串必须完全匹配模式
- (-m sub) 在提取的字符串中查找,如果其中任何一个被发现,ACL将匹配
- (-m beg) 在提取的字符串首部中查找,如果其中任何一个被发现,ACL 将匹配
- (-m end) 在提取的字符串尾部中查找,如果其中任何一个匹配,则 ACL 进行匹配
- (-m dir) 提取用斜线 / 分隔的字符串,如果其中任何一个匹配,则 ACL 进行匹配
- (-m dom) 提取用点 . 分隔字符串,如果其中任何一个匹配,则 ACL 进行匹配
- <value> 条件目标
- 布尔值: 比如 false,true
- 整数或整数范围,比如用于匹配端口范围: 1024 ~ 32768
- IP 地址或 IP 范围: 192.168.0.1 ~ 192.168.0.1/24
- 字符串: 比如匹配 URL 路径,/static 、/images
5.1.1 src
- src <string> 用于测试请求的源地址是否与 <string> 中定义的源地址一致
1 | # 示例: 匹配请求源地址是 10.0.0.1、或 192.168.0.0/24 网段 |
5.1.2 path_beg
- path_beg <string> 用于测试请求的 URL 是否以 <string> 指定的模式开头
1 | # 示例: 测试 URL 是否以 /static 、 /images 、 /javascript 开头 |
5.1.3 hdr_beg
- hdr_beg <string> 用于测试请求报文的指定首部的开头部分是否符合<string>指定的模式
1 | # 示例: 测试请求的host开头是否为,img、video、static |
5.1.4 hdr_end
- hdr_end
用于测试请求报文的指定首部的结尾部分是否符合 指定的模式
1 | # 示例: 测试请求的host的结尾是否为 .com .net .cn |
5.1.5 hdr_dom
- hdr_dom(host) 用于测试请求的 host 名称
1 | # 示例: 测试请求的 host 是否为 web.ink8s.com |
5.1.6 hdr
- hdr <string> 用于测试请求头部首部指定内容
1 | # 示例: 测试请求的 User-Agent 是否为 Chrome |
5.2 ACL 逻辑关系
- 多个 acl 作为条件的逻辑关系
- 与: 默认,如 if acl1 acl2 表示满足第一个 acl 的同时要满足第二 acl 此条件才为真
- 或: 使用 or 或 || 表示,如 if acl1 || acl2 表示满足 acl1 或 acl2 中的任意一个此条件就为真
- 非: 使用 ! 表示,如 if ! acl1 表示对该 ACL 取相反的操作,意思就是非该 ACL 此条件为真
5.3 ACL 访问控制
5.3.1 基于 HTTP 访问控制
- 配置7层的请求访问控制;只能用在 mode http 中
- http-request { allow | deny } [ { if | unless } <condition> ]
- 示例: 仅允许 10.10.10.100 访问 haproxy 的 stats
1 | # cat /data/apps/haproxy/conf/conf.d/stats.ink8s.com.cfg |
- 本文作者: [email protected]
- 本文链接: https://www.ink8s.com/2024/01/21/haproxy-负载均衡/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!