HAProxy(High Availability Proxy)简述
一、简介
- HAProxy 是一款提供高可用性、负载均衡以及基于TCP(第四层)和HTTP(第七层)应用的代理软件,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。 HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。HAProxy运行在时下的硬件上,完全可以支持数以万计的 并发连接。并且它的运行模式使得它可以很简单安全的整合进您当前的架构中, 同时可以保护你的web服务器不被暴露到网络上。
- HAProxy 实现了一种事件驱动、单一进程模型,此模型支持非常大的并发连接数。多进程或多线程模型受内存限制 、系统调度器限制以及无处不在的锁限制,很少能处理数千并发连接。事件驱动模型因为在有更好的资源和时间管理的用户端(User-Space) 实现所有这些任务,所以没有这些问题。此模型的弊端是,在多核系统上,这些程序通常扩展性较差。这就是为什么他们必须进行优化以 使每个CPU时间片(Cycle)做更多的工作。
- HAProxy 支持连接拒绝 : 因为维护一个连接的打开的开销是很低的,有时我们很需要限制攻击蠕虫(attack bots),也就是说限制它们的连接打开从而限制它们的危害。 这个已经为一个陷于小型DDoS攻击的网站开发了而且已经拯救了很多站点,这个优点也是其它负载均衡器没有的。
- HAProxy 支持全透明代理(已具备硬件防火墙的典型特点): 可以用客户端IP地址或者任何其他地址来连接后端服务器. 这个特性仅在Linux 2.4/2.6内核打了cttproxy补丁后才可以使用. 这个特性也使得为某特殊服务器处理部分流量同时又不修改服务器的地址成为可能。
优点
- 高性能:HAProxy 采用事件驱动的架构,可以处理海量的并发连接,有着出色的性能表现
- 高可靠性:HAProxy 支持故障检测和自动切换等高可用特性,确保服务的稳定性和可靠性
- SSL/TLS 终端:HAProxy 支持 SSL/TLS 终端,可以对 HTTPS 流量进行处理,提供了安全性保障
- 监控和统计:HAProxy 提供丰富的监控指标和统计信息,可以轻松查看系统运行状态
- 负载均衡:HAProxy 支持多种负载均衡算法,如轮询、加权轮询、最少连接等,可根据实际需求进行灵活配置
负载均衡算法
- roundrobin: 轮询算法。按照服务器列表的顺序逐个转发请求。这是默认的算法
- static-rr: 静态加权轮询算法。与 roundrobin 类似,但可以为每个服务器指定权重
- leastconn: 最少连接算法。将请求转发到当前连接数最少的服务器。适用于长连接场景
- source: 基于客户端源IP的哈希算法。将来自同一IP的请求转发到同一台服务器。适用于需要保持会话的场景
- uri: 基于请求URI的哈希算法。将同一URI的请求转发到同一台服务器。适用于缓存场景
- url_param: 基于URL参数的哈希算法。将包含指定参数的请求转发到同一台服务器
- hdr(name): 基于HTTP头部的哈希算法。将包含指定头部的请求转发到同一台服务器
- rdp-cookie: 基于 RDP cookie 的哈希算法。适用于 RDP 协议
- firstly: 首选算法。选择第一个可用的服务器
- random: 随机算法。随机选择一台服务器转发请求
- tunnel: 隧道算法。保持连接在同一服务器上
- leasttime: 最短响应时间算法。选择响应时间最短的服务器
二、安装配置
2.1 安装
# 直接使用RPM来安装 yum -y install haproxy # 查看安装版本 rpm -qi haproxy # 查看安装版本的文件以及路径 rpm -ql haproxy
2.2 配置文件
默认配置文件路径 /etc/haproxy/haproxy.cfg ,haproxy配置文件分为五个部分
2.2.1 global
全局配置主要用于设定义全局参数,属于进程级的配置,通常和操作系统配置有关
global # to have these messages end up in /var/log/haproxy.log you will # need to: # # 1) configure syslog to accept network log events. This is done # by adding the '-r' option to the SYSLOGD_OPTIONS in # /etc/sysconfig/syslog # # 2) configure local2 events to go to the /var/log/haproxy.log # file. A line like the following can be added to # /etc/sysconfig/syslog # # local2.* /var/log/haproxy.log # log 127.0.0.1 local2 # 日志输出设置,默认存到本地,日志级别为INFO #log 127.0.0.1 local0 info # 配置日志级别为 info chroot /var/lib/haproxy # chroot运行路径 pidfile /var/run/haproxy.pid # haproxy 进程PID文件 maxconn 4000 # 默认最大连接数 user haproxy # 运行用户 group haproxy # 运行用户组 daemon # 以守护进程的方式运行,也就是在后台运行 # turn on stats unix socket stats socket /var/lib/haproxy/stats # 统计信息 Unix 套接字路径
2.2.2 defaults
默认配置段设置的参数会被haproxy.cfg的其他配置段继承,如frontend、backend和 listen配置段都会继承 default配置段参数,因此,对于公用的配置在此统一配置。
但如果frontend、backend、listen部分也配置了与defaults部分一样的参数,defaults部分参数对应的值自动被覆盖。
defaults mode http # 指定连接协议(7层代理http,4层代理tcp) log global # 引入global定义的日志格式 option httplog # 日志类别为http日志格式 option dontlognull # 不记录空连接日志信息 option http-server-close # 在与后端服务器通信结束后立即关闭连接,若需要长连接则注释掉此配置 option forwardfor except 127.0.0.0/8 # 在转发请求时,添加 X-Forwarded-For 请求头(127.0.0.0/8除外),用于后端服务器上识别真实的客户端 IP 地址 option redispatch # 在服务器故障时自动将会话重新分配到其他服务器,避免单点故障 # 当使用了 cookie时,haproxy将会将其请求的后端服务器的serverID插入到cookie中,以保证会话的SESSION持久性;而此时,如果后端的服务器宕掉了,但是客户端的cookie是不会刷新的,如果设置此参数,将会将客户的请求强制定向到另外一个后端server上,以保证服务的正常。
retries 3 # 3次连接失败就认为服务器不可用 timeout http-request 10s # 默认http请求超时时间 timeout queue 1m # 默认队列超时时间,当后端服务器负载高,无法立即处理 HAProxy 转发过来的请求时,HAProxy 会将这些请求临时放入一个队列中,等待后端服务器空闲后再进行转发 timeout connect 10s # 默认连接超时时间 timeout client 1m # 默认客户端空闲时间,超时无交互则关闭客户端连接 timeout server 1m # 默认服务端空闲时间,haproxy与后端超过此时间无交互,则关闭这个服务器连接 timeout http-keep-alive 10s # 默认持久连接超时时间 timeout check 10s # 默认心跳检查超时时间 maxconn 3000 # 最大连接数,当与global配置不一样时,此处配置生效
2.2.3 frontend
前端配置,配置监听客户端请求的 IP地址和端口,在高可用环境下,此处的监听 IP地址通常为虚拟 IP;并将监听到的客户端请求转发到指定的后端配置中进行负载均衡。
frontend main *:5000 # 监听本机5000端口;可自定义ip跟端口,如:bind 0.0.0.0:8080 acl url_static path_beg -i /static /images /javascript /stylesheets # 匹配以/static、/images、/javascript、/stylesheets 开头的 URL acl url_static path_end -i .jpg .gif .png .css .js # 匹配以 .jpg、.gif、.png、.css、.js 结尾的 URL,通常为动态资源 use_backend static if url_static # 如果请求匹配 url_static ACL,则转发到 static 后端服务器 default_backend app # 默认后端服务器组,如果请求不匹配 url_static ACL,则转发到 app 后端服务器
上述示例中还涉及到了ACL的使用,HAProxy 中的 ACL (Access Control List) 是一个非常强大的功能,用于根据请求的各种特征进行条件匹配和判断。ACL 可以根据需求对请求进行路由、限速、访问控制等操作,广泛应用于负载均衡、流量控制、安全防护等场景。
2.2.4 ACL
ACL定义:<name> 是规则的名称,<criterion> 是匹配条件,<value> 是可选的匹配值。
acl <name> <criterion> [<value>]
匹配条件:
path_beg
: 请求路径以指定值开头path_end
: 请求路径以指定值结尾path
: 请求路径完全匹配指定值hdr(name)
: 请求头中name
字段的值匹配指定值method
: 请求方法匹配指定值(如 GET、POST 等)src
: 客户端 IP 地址匹配指定值dst
: 目标服务器 IP 地址匹配指定值ssl_fc
: 如果连接是 HTTPS 则匹配
操作符:
-i
: 大小写不敏感- -m: 使用正则匹配
!
: 否定匹配or
/and
: 多个条件组合
使用ACL:
- use_backend:根据指定的 ACL 条件将请求路由到某个后端服务器组
- redirect:对请求进行重定向。可以设置重定向的状态码、目标 URL 前缀等
- default_backend:默认的后端服务器组。如果前面的 use_backend 规则都不匹配,则将请求路由到此处指定的后端服务器组
示例:
2.2.4.1 基于路径和请求方法的访问控制
acl is_static path_end .jpg .jpeg .gif .png .css .js #路径结尾 acl is_admin hdr(X-Admin) true #请求头包含X-Admin: true acl is_post method POST #请求方法POST use_backend static if is_static #如果请求路径以静态资源扩展名结尾,则路由到 static 后端 use_backend admin if is_admin #如果请求头包含 X-Admin: true,则路由到 admin 后端 use_backend app if !is_static !is_admin is_post #如果不是静态资源也不是管理员请求,且请求方法是 POST,则路由到 app 后端
2.2.4.2 基于客户端 IP 和 HTTPS 的访问控制
acl is_local src 192.168.1.0/24 acl is_https ssl_fc use_backend local_app if is_local #如果客户端 IP 在 192.168.1.0/24 网段内,则路由到 local_app 后端 use_backend public_app if !is_local #如果客户端 IP 不在内网网段,则路由到 public_app 后端 redirect scheme https if !is_https #如果请求不是 HTTPS,则重定向到 HTTPS
2.2.4.3 基于多个条件的组合
acl is_static path_end .jpg .jpeg .gif .png .css .js acl is_mobile hdr(User-Agent) -i -m found,mobile acl is_admin hdr(X-Admin) true use_backend static if is_static #如果请求路径是静态资源,则路由到 static 后端 use_backend mobile if is_mobile !is_static #如果请求是移动设备,且不是静态资源,则路由到 mobile 后端 use_backend admin if is_admin !is_static !is_mobile #如果请求是管理员,且不是静态资源也不是移动设备,则路由到 admin 后端
2.2.5 backend
后端配置,用来定义后端服务集群的配置,真实服务器,一个Backend对应一个或者多个实体服务器
backend static # 定义服务器组 balance roundrobin # 负载均衡算法,轮询 server static 127.0.0.1:4331 check # 定义后端真实服务器,并启用健康检查 #--------------------------------------------------------------------- # round robin balancing between the various backends #--------------------------------------------------------------------- backend app balance roundrobin server app1 127.0.0.1:5001 check # 此处额外定义了后端服务器的名称为app1 server app2 127.0.0.1:5002 check server app3 127.0.0.1:5003 check server app4 127.0.0.1:5004 check
2.2.6 listen(可选)
HAProxy为每个监听代理提供了实时监控,并可以将监控参数以 GUI页而的形式呈现给用户。手动添加以下配置:
listen admin_status # 监控组的名称,自定义 bind 0.0.0.0:8888 # 监听端口 mode http # http的7层模式 log 127.0.0.1 local3 err # 错误日志记录 stats refresh 5s # 每隔5秒自动刷新监控页面 stats uri /admin # 监控页面的url访问路径 stats realm itnihao\ welcome # 监控页面的提示信息 stats auth admin:admin # 监控页面的用户和密码admin,可以设置多个用户名 stats auth admin1:admin1 # 监控页面的用户和密码admin1 stats hide-version # 隐藏统计页面上的HAproxy版本信息
浏览器访问(需登录)
各参数含义如下:
(1)Queue cur:表示当前队列的请求数量。 Max:表是当前队列最大的请求数量。 Limit:表示队列的限制数量。 (2) Session rate Cur:每秒会话连接数量。 Max:每秒会话数量最大值。囗 Limit:每秒会话数量的限制值。 (3) Sessions Total:总共会话数量。 Cur:当前的会话数量。 Max:最大会话数量。 Limit;会话连接限制。 Lbtot:选中一台服务器所用的总时间。 Last:最后一次会话时间。 (4) Bytes In:网络会话输人字节数总量。 Out:网络会话输出字节数总量。 (5) Denied Req:被拒绝的会话请求数量。 Resp:拒绝回应的请求数量。 (6) Errors Req:错误的请求数量。 Conn:错误连接数量。 Resp:错误响应数量。 (7) Warnings Retr:重新尝试连接的请求数量。 Redis:重新发送的请求数量。 (8) Server status:后端服务器状态,可以有 UP和 DOWN两种状状态。 LastChk:持续检查后端服务器的时间。 Wght:服务器权重。 Act:活动后端服务器数量。 Bck:后端备份服务器的数量。 Down:状态为 Down的后端服务器数量。 Downtime:服务器总的 Downtime时间。 Throttle:状态 Backup变为 Active的服务器数量。
三、启停
# 使用 systemd 启动 systemctl start haproxy # 指定配置文件启动 /usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg # 以守护进程模式启动 /usr/sbin/haproxy -D -f /etc/haproxy/haproxy.cfg
# 使用 systemd 停止
systemctl stop haproxy
# kill pid
四、HAProxy + Keepalived 高可用
这里共使用两台服务器,每台服务器上运行haproxy和keepalived进程;两台haproxy配置都一样,frontend绑定的ip为keepalived创建的vip,由keepalived来做故障切换,haproxy做负载均衡。
配置示例
HAProxy配置(两台服务器一致)
... frontend http bind 192.168.1.100:80 default_backend web_servers backend web_servers server web1 10.0.0.101:80 check server web2 10.0.0.102:80 check balance roundrobin ...
Keepalived 配置 (两台服务器略有不同)
# Master HAProxy global_defs { router_id LVS_DEVEL } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1234 } virtual_ipaddress { 192.168.1.100 } } # Backup HAProxy global_defs { router_id LVS_DEVEL } vrrp_instance VI_1 { state BACKUP interface eth0 virtual_router_id 51 priority 90 advert_int 1 authentication { auth_type PASS auth_pass 1234 } virtual_ipaddress { 192.168.1.100 } }
五、补充
5.1 日志管理
大规模集群中,日志只保存本地的话,不便统一查看,可以将日志发送至专门的日志服务器中管理。
注:注意本地日志文件要定期进行归档,压缩以及删除,防止日志文件占用太多磁盘空间。
global log 10.0.0.100:514 local0 #将日志发送到 IP 为 10.0.0.100,端口为 514 的日志服务器,使用 local0 设施。 log /var/log/haproxy.log local0 #将日志记录到本地文件 log-send-hostname #在日志中添加主机名信息 ... frontend www # ... option httplog log global #使用global中的日志配置 backend web_servers # ... option httplog log global