1.Haproxy简单介绍
什么是Haprxoy
Haproxy虽然叫ha,但是不提供HA高可用
功能,而是提供proxy
代理功能,支持代理TCP、HTTP
等协议。
Haproxy提供对后端进行状态检测功能,一但后端节点出现故障,会重新分发请求,这也是称为haproxy的原因。
Haproxy应用场景
- 支持HTTP反向代理
- 支持动态程序的反向代理
- 支持基于数据库的反向代理
Haproxy性能指标
- 会话率:会话建立的速率,能在1s内建立多少链接
- 会话并发能力:整体服务器的会话并发能力,能支持多少并发
- 数据率:在所有会话基础上,数据传输速率或数据传输效率
正如在基于AWS ARM的Gravion2上的测试运行所示,HAProxy在线程上扩展得很好,并且能够通过SSL达到200万个请求/秒,对于转发流量,可以达到100 Gbps。
这是在说haproxy的性能贼好!
2.Haproxy安装
yum安装
- 如果你为了方便,且并发很小的话,你用yum安装也无妨,版本在1.5.18,且许多新功能是没有的。
# 安装 yum -y install haproxy # 删除的话可以用这个 yum -y erase haproxy
第三方仓库安装
wget https://repo.ius.io/ius-release-el7.rpm rpm -Uvh --nodeps ius-release-el7.rpm yum -y install haproxy22 # 装出来是一个2.2.18版本,不是最新但比较新 haproxy -v HA-Proxy version 2.2.18-c6e1dfa 2021/11/05 - https://haproxy.org/ Status: long-term supported branch - will stop receiving fixes around Q2 2025. Known bugs: http://www.haproxy.org/bugs/bugs-2.2.18.html Running on: Linux 4.19.12-1.el7.elrepo.x86_64 #1 SMP Fri Dec 21 11:06:36 EST 2018 x86_64
源码安装
- 如果你想使用最新的稳定版,可以尝试编译安装,太麻烦我不装了,看别人的去就行。
3.配置文件
- 配置文件默认路径
/etc/haproxy/haproxy.cfg
- 配置文件分为global全局段和代理段
- 代理段包括前端匹配(frontend)、后端集群(backend)以及两者结合(listen)
3.1.global全局段常见配置
daemon:以守护进程运行(后台运行),没有的话会挂载前台 chroot /var/lib/haproxy :锁定运行目录,比较安全 user haproxy :用户 group haproxy :用户组 maxconn 4000 :每个haproxy进程所接受最大并发连接数,注意是每个进程 cpu-map 1 0 :cpu亲和,第一个参数进程编号,第二个cpu序号,配合nbproc使用 nbproc <n> :指定启动进程数,默认一个 nbthread <n> :指定线程数,默认一个,不能与nbproc同时使用 log 127.0.0.1 local2 :日志记录,通过本地rsyslog的local2设备记录 stats socket /var/lib/haproxy/stats :基于socket通信,可实现动态变更配置 spread-checks <0..10, in percent> :健康检查范围
- 多进程示例:
# 默认配置开启进程 ps -ef | grep haproxy root 2642 1 0 09:20 ? 00:00:00 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid haproxy 2645 2642 0 09:20 ? 00:00:00 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid root 2648 2462 0 09:20 pts/1 00:00:00 grep --color=auto haproxy # 修改配置文件,在global配置 nbproc 4 # 重启后,查看进程 systemctl restart haproxy ps -ef | grep haproxy root 2659 1 0 09:22 ? 00:00:00 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid haproxy 2663 2659 0 09:22 ? 00:00:00 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid haproxy 2664 2659 0 09:22 ? 00:00:00 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid haproxy 2665 2659 0 09:22 ? 00:00:00 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid haproxy 2666 2659 0 09:22 ? 00:00:00 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid root 2668 2462 0 09:23 pts/1 00:00:00 grep --color=auto haproxy
- 配置haproxy日志,默认是没有日志的,需要自行配置
# haproxy中默认配置好了日志 log 127.0.0.1 local2 # 配置rsyslog文件 vim /etc/rsyslog.conf $ModLoad imudp $UDPServerRun 514 local2.* /var/log/haproxy.log systemctl restart rsyslog.service systemctl restart haproxy # 访问测试 tail -f /var/log/haproxy.log Dec 17 09:42:47 localhost haproxy[3067]: Proxy main started. Dec 17 09:42:47 localhost haproxy[3067]: Proxy static started.
3.2.default默认区段(不经常用)
option参数
- option httplog:记录日志,包括但不限于HTTP请求、连接计时器、会话状态、连接数、捕获的首部及cookie、frontend、backend等
- option dontlognull:不记录健康检查的日志信息
- option redispatch:当找不到cookie对应服务器时,重新分配新的节点给客户端
- option forwardfor:传递客户端真实IP
timeout参数
·timeout http-request 30s:客户端发送http请求的超时时间
·timeout queue 1m:请求超过最大并发连接数,多余请求进入队列,等待的超时时间
··timeout connect 10s:haproxy与后端连接超时时间
timeout client 1m:非活动连接超时时间
- timeout server 1m:haproxy与后端非活动连接超时时间
- timeout http-keep-alive 60s:HTTP请求连接建立的最大超时时间
- timeout check 10s:健康检测时间的最大超时时间
3.3.proxy区段配置
代理相关配置
- frontend (name):用于定义系列监控的端口,这些端口可接受客户端请求并连接
- backend (name):用于定义一系列后端服务器,代理将会将对应客户端请求分发至这些服务器
- listen (name):通过关联“前端”和“后端”定义一个完整的代理
mode参数:定义haproxy示例运行的协议
- 语法:mode {tcp|udp}
- tcp:不对7层报文做任何检查;通常用于ssl、ssh、mysql等应用
- http:客户端请求服务器,服务端重新封装请求报文,请求后端真实节点
- 示例:
listen www *:80 mode http server web01 192.168.10.3:80
maxconn:一个前端的最大并发连接数,不可超过全局,优先级比全局高
- haproxy会为每个连接维持两个缓冲,每个缓冲的大小为8KB,加上其他数据大概共占用17KB左右。意味着优化后1GB的RAM空间可以维护40000-50000并发连接
server参数:为后端定义一个server节点
- 为后端声明一个server节点信息,不能用于default和frontend区段
- 语法:server [name] [address]:[port] [param*]
# param常用参数: backup:正常节点异常后启用备用节点 check:对此server进行tcp的健康检查;check port 80 inter:健康检查的时间间隔;check inter 3000 rise:设置离线状态转正常状态需要成功检查的次数 fall:设置正常状态转不可用状态检查的次数 maxconn:设置此服务器接收最大的并发连接数 maxqueue:设置请求队列的最大长度 weight:服务器节点权重,默认为1,最大256,0表示不参加负载均衡
bind:绑定的端口
- 示例:bind *:8080
4.haproxy调度算法
- 根据后端服务器的负载,或其他计算的标准,判断挑选哪台RS来进行请求处理
- 调度算法可用于“default、listen、backend”
roundrobin:轮询
- 基于权重进行轮询,保持均匀分布,是比较平衡公平的算法
- 此算法是动态的,权重可以进行调整,但是每个后端服务器最多接受4128个连接
- 示例:
frontend main bind *:80 mode http use_backend web backend web balance roundrobin server web01 192.168.10.3:80 check server web02 192.168.10.4:80 check
static-rr:静态轮询
- 加权轮询调度算法,根据服务器的硬件情况、处理能力,为每台服务器分配不同的权值
- 此算法为静态,不可在运行时进行调整
- 示例:访问时按2、3的规则分配
backend web balance static-rr server web01 192.168.10.3:80 check weight 2 server web02 192.168.10.4:80 check weight 3
leastconn
- 新的连接请求被派发至具有最少连接数目的服务器
- 此算法为动态,可以在运行时调整权重
source
- 源地址hash调度算法,将请求的源地址进行‘hash’运算,得到一个具体的数值,同时对后端服务器进行编号,按照运算结果将请求发到对应编号的服务器上。
- 这样可对不同源IP的访问进行负载分发,对同一个客户端IP请求始终分发到特定的服务器
- 如果添加新机器或宕机,客户端请求也可能会派发至与之前不同的服务器
- 可通过hash-type修改特性:hash-type {map-based|consistent}
- 示例:
backend web balance source hash-type consistent server web01 192.168.10.3:80 check weight 2 server web02 192.168.10.4:80 check weight 3
uri
- 基于对用户请求uri做hash并将请求转发至后端服务器
- 同一个节点访问不同的uri会被调度到不同的后端服务器;不同节点访问相同的uri会被调度到同一台服务器
- 此算法仅用于http后端服务器场景;默认为静态,可以修改
url_param
- 对用户请求的url中的param参数中的name做调度
- 一个url中?后的name中内容
- 通常用于追踪用户,以确保来自同一个用户请求始终发往同一个backend server(使用少)
hdr
- 针对用户发起HTTP请求中header中的name关键字进行hash计算,如果没有有效的值,则会进行轮询(使用少)
5.ACL
- acl主要对请求报文和响应报文进行匹配和过滤。
- 首先定义acl规则,即定义一个测试条件,条件可以是请求报文中的源地址、源端口、目标地址、目标端口、请求方法、URL、文件后缀等。
- 然后在条件得到满足时执行相应的动作;比如阻止请求、又或者转发请求至某特定后端。
- 语法:
acl <aclname> <criterion> [flags] [operator] [value] 即: acl acl名称 条件 条件标记位 具体操作符 操作对象类型
- aclname:ACL名称,可使用字母、数字和:. - _区分字符大小写
- criterion:比较的条件标准
基于源地址、源端口、目标地址、目标端口:src、src_port、dst、dst_port 基于Header信息对比:hdr、hdr_beg、hdr_end、hdr_dom 基于路径或后缀:path_beg、path_end 基于请求方法比对:method
- 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地址或范围: 字符串:比如匹配URL路径,/static\/images等
- 逻辑关系:多个acl作为条件时的逻辑关系(||、!)
- 示例:基于http访问,来源用户非127.0.0.1则拒绝
acl source_ip src 192.168.10.100 http-request deny if !source_ip
。。 。 。。。。 。。。。 。。。。 。