HAProxy(High Availability Proxy)是一款利用C语言编写的,高性能的开源负载平衡器和代理服务器软件,专为TCP(L4)和HTTP(L7)应用而操持。它可以将客户端的请求分发到多台后端服务器,从而提高应用的可用性和性能。HAProxy支持多种负载平衡算法和康健查抄机制,是构建高可用性体系的抱负选择。
LB(Load Balance,负载平衡):是一种服务或基于硬件设备等实现的高可用反向代理技能,负载平衡将特定的业务(web服务、网络流量等)分担给指定的一个或多个后端特定的服务器或设备,从而提高了公司业务的并发处理能力、保证了业务的高可用性、方便了业务后期的水平动态扩展。
OSI 网络七层模型(OSI:Open System Interconnection, 开放体系互联)
根据 OSI模型 可将负载平衡分为:
- 二层负载平衡(mac):一般是用假造mac地址方式,外部对假造MAC地址请求,负载平衡接收后分配后端实际的MAC地址响应;
- 三层负载平衡(ip):一般接纳假造IP地址方式,外部对假造的ip地址请求,负载平衡接收后分配后端实际的IP地址响应;
- 四层负载平衡(tcp):在三次负载平衡的底子上,用 ip+port 接收请求,再转发到对应的机器;(如:F5,lvs,nginx,haproxy)
- 七层负载平衡(http):根据假造的url或是IP,主机名接收请求,再转向相应的处理服务器。(如:haproxy,nginx,apache)
负载平衡模型介绍
- 无负载平衡:没有负载平衡的简朴Web应用程序情况,如下所示
示例中,用户直接连接到您的Web服务器,在 yourdomain.com 上,并且没有负载平衡。大概遇到的问题:
- 如果单个Web服务器出现故障,用户将无法再访问您的Web服务器。
- 如果很多用户试图同时访问您的服务器,并且无法处理负载,他们大概会遇到缓慢的体验,大概大概根本无法连接。
- 四层负载平衡:根据IP范围和端口转发用户流量
将网络流量负载平衡到多个服务器的最简朴方法是利用第4层(传输层)负载平衡。
示例中,用户访问负载平衡器,负载平衡器将用户的请求转发给后端服务器的Web后端组。
- 无论选择哪个后端服务器,都将直接响应用户的请求。
- 通常,Web后端中的所有服务器应该提供相同的内容(否则用户大概会收到不同等的内容)。
- 七层负载平衡:根据用户请求的内容将请求转发到不同的后端服务器
七层负载平衡是更复杂的负载平衡,这种模式是利用第7层(应用层)负载平衡。它答应您在同一域和端口下运行多个Web应用程序服务器。
示例中,如果用户请求 yourdomain.com/blog,则会将其转发到博客后端,后端是一组运行博客应用程序的服务器。其他请求被转发到web-backend,后端大概正在运行另一个应用程序。
四层和七层负载平衡的区别:
- 四层的负载平衡:通过发布三层的IP地址(VIP),然后加四层的端标语,来决定哪些流量需要做负载平衡,对需要处理的流量进行NAT处理,转发至后台服务器,并记载下这个TCP大概UDP的流量是由哪台服务器处理的,后续这个连接的所有流量都同样转发到同一台服务器处理。
- 七层的负载平衡:在四层的底子上(没有四层是绝对不大概有七层的),再考虑应用层的特征,比如同一个Web服务器的负载平衡,除了根据VIP加80端口辨别是否需要处理的流量,还可根据七层的URL、欣赏器类别、语言来决定是否要进行负载平衡
一、介绍
HAProxy 是一款 TCP/HTTP 反向代理负载平衡服务器软件,可工作在OSI模型中的四层传输层以及七层应用层。
HAProxy特别适用于那些负载压力大的web站点,这些站点通常需要会话保持或七层处理。
HAproxy答应用户界说多组服务代理,代来由前端和后端组成,前端界说了服务监听的IP及端口,后端则界说了一组服务器及负载平衡的算法。通过服务代理将流量由前端负载平衡至后端服务器节点上。
HAProxy的工作流程如下:
- 客户端发送请求到HAProxy的前端(frontend)。
- 前端根据配置的规则,选择合适的后端(backend)。
- 后端将请求分发到具体的服务器进行处理。
- 服务器处理请求并返回结果,通事后端和前端返回给客户端。
1.1 核心
- 负载平衡:拥有 L4 和 L7 两种负载平衡模式,支持多种负载平衡算法(如:RR/静态RR/LC/IP Hash/URI Hash/URL_PARAM Hash/HTTP_HEADER Hash等)。
- 会话保持:确保同一客户端的所有请求都分配到同一台服务器处理。对于未实现会话共享的应用集群,可根据 Hash 大概 cookies 方式实现会话保持。(如:source、Insert Cookie和Prefix Cookie等)
- 康健查抄:通过定期检测服务器状态,动态调整服务器的可用性。支持 TCP、HTTP 两种后端服务器康健查抄模式。
- 统计监控:接受访问特定端口实现服务监控(提供了基于Web的,并带有用户认证机制的统计信息页面,展现服务康健状态和流量数据)。
- SSL卸载:可以解析 HTTPS 报文,并将请求解密为 HTTP 向后端服务器传输。
- 其他功能:
- 在 HTTP 请求或响应报文中添加、修改、删除头部信息;
- HTTP 请求重写 与重定向;
- 根据访问控制路由或阻断请求。
1.2 上风
- 高性能: 接纳异步事件驱动架构,能够高效处理大量并发连接。
- 高可用:通过康健查抄和故障转移机制,确保服务的可靠性。
- 机动性强:支持多种负载平衡算法和调度策略,适应不同的应用场景。
- 模块化: 支持多种模块扩展,如 HTTP、TCP、SSL/TLS 等。
- 丰富的功能:支持SSL终止、HTTP重写、压缩等多种功能。
- 简朴易用: 配置语法简洁,易于上手。
点击了解《HAProxy 与 NGINX:全面比较》
二、安装
haproxy官网:https://www.haproxy.org/
2.1 yum 安装
sudo yum install haproxy -y
注意: yum 安装的 HAProxy 版本大概比较旧,建议利用编译安装方式获取最新版本。
2.2 rpm 包安装
从第三方网站下载 rpm 包进行安装,比方:https://pkgs.org/download/haproxy
注意: 下载 rpm 包时,请务必选择可靠的来源,并注意版本兼容性。
2.3 编译安装
<ol>安装依靠包
sudo yum install -y make gcc pcre pcre-devel bzip2-devel openssl openssl-devel
下载并编译安装- #下载安装包,并解压
- wget https://www.haproxy.org/download/3.0/src/haproxy-3.0.9.tar.gz
- tar -xzf haproxy-3.0.9.tar.gz
- cd haproxy-3.0.9
- #编译安装
- make TARGET=linux-glibc USE_OPENSSL=1 USE_PCRE=1 USE_SYSTEMD=1
- sudo make install PREFIX=/usr/local/haproxy
- #创建软链接(可选)
- sudo ln -s /usr/local/haproxy/sbin/haproxy /usr/sbin/
复制代码
- TARGET:指定目标操作体系和内核版本。
- haproxy-2.x 及以下版本安装时:TARGET=linux2628 .(linux2628 表示目标是 Linux 体系,内核版本为 2.6.28 或更高版本。这个参数确保 HAProxy 在编译时针对特定的内核版本进行优化。)
- haproxy-3.x 版本安装时: TARGET=linux-glibc .
- USE_OPENSSL=1:启用对 OpenSSL 的支持。这使得 HAProxy 能够处理 SSL/TLS 加密的流量。
- 如果你需要 HAProxy 支持 HTTPS 或其他加密协议,这个选项是必需的。
- USE_PCRE=1:启用对 PCRE(Perl Compatible Regular Expressions)库的支持。PCRE 库用于支持正则表达式。
- 这对于 HAProxy 的一些高级功能(如基于 URL 的路由规则)是须要的。
- USE_SYSTEMD=1:启用对 systemd 的支持。systemd 是一个体系和服务管理器,用于启动、制止和管理服务。
- 启用这个选项可以让 HAProxy 与 systemd 集成,从而更方便地管理 HAProxy 服务
- PREFIX:指定的安装路径。
配置并验证- #创建服务用户
- sudo useradd -r -M -s /sbin/nologin haproxy
- #创建配置文件目录
- sudo mkdir /etc/haproxy
- #使用配置文件(可选)
- sudo cp addons/ot/test/empty/haproxy.cfg /etc/haproxy
- #验证 HAProxy 配置
- sudo haproxy -f /etc/haproxy/haproxy.cfg -c
- #启动测试
- sudo haproxy -f /etc/haproxy/haproxy.cfg
复制代码 创建 HAProxy 服务文件- sudo tee /etc/systemd/system/haproxy.service <<-EOF
- [Unit]
- Description=HAProxy Load Balancer
- After=syslog.target network.target
- [Service]
- Environment="CONFIG=/etc/haproxy/haproxy.cfg" "PIDFILE=/run/haproxy.pid"
- ExecStartPre=/usr/sbin/haproxy -f \$CONFIG -c -q
- ExecStart=/usr/sbin/haproxy -Ws -f \$CONFIG -p \$PIDFILE
- ExecReload=/usr/sbin/haproxy -f \$CONFIG -c -q
- ExecReload=/bin/kill -USR2 \$MAINPID
- KillMode=mixed
- Restart=always
- Type=notify
- [Install]
- WantedBy=multi-user.target
- EOF
复制代码
- action:主要操作模式 (必选其一)
- insert - HAProxy 主动插入一个新 Cookie
- prefix - 在应用已有的 Cookie 值前添加服务器标识
- rewrite - 完全重写应用设置的 Cookie (不推荐,大概破坏应用)
- params:可选修饰参数
- indirect - 如果客户端已携带指定 Cookie,则不插入/修改
- nocache - 禁止代理 /CDN 缓存带有此 Cookie 的响应
- httponly - 设置 HttpOnly 标志,限制 cookie 只能通过 HTTP 访问(防止 JavaScript 访问)
- secure - 仅通过 HTTPS 传输 Cookie
- domain - 设置 Cookie 的作用域域名
- maxidle - 设置 Cookie 空闲逾期时间(秒)
- maxlife - 设置 Cookie 绝对逾期时间(秒)
- dynamic - 答应利用动态 Cookie 值
- attr - 设置额外的 Cookie 属性(如 SameSite)
server [:] [params ...]
- name: 服务器在配置中的唯一标识名称
- address: 服务器的 IP 地址或主机名
- port: 服务器监听的端口(可选,默认利用 backend 界说的端口)
- params: 可选的服务器参数
- 康健查抄参数:
- check: 启用康健查抄(默认不查抄),注意必须指定端口才气实现康健性查抄
- inter : 康健查抄间隔(默认2000 ms,2s)
- rise : 将服务器标记为"正常"所需连续乐成查抄次数(默认2s)
- fall : 将服务器标记为"故障"所需连续失败查抄次数(默认3s)
- 负载平衡参数:
- weight : 服务器权重(用于加权轮询,默认1)
- backup: 标记为备份服务器(仅当所有非备份服务器不可用时利用)
- 连接参数:
- maxconn : 最大并发连接数,当连接数到达maxconn后,新连接会进入期待队列(默认0,即无限)
- maxqueue : 最大队列长度,当队列已满后,新请求会发至此backend下的其他server(默认0,即无限)
- SSL/TLS 参数:
- ssl: 启用 SSL/TLS 连接到后端
- verify [none|required]: SSL 证书验证
- 其他参数:
- cookie :指定 server 每行的唯一标识(用于共同基于cookie的会话保持)
- disabled:将后端服务器标记为"不可用状态",即维护状态,除了持久模式
例子:- defaults
- log global
- option httplog
- log 127.0.0.1 local2
复制代码 3.5 聚合配置(listen)
listen 是HAProxy配置中的一个重要部分,它答应在一个配置块中同时界说前端(frontend)和后端(backend)的设置,简化了配置过程,特别适用于简朴的代理场景。
listen指令提供了一种简洁的方式来配置HAProxy,将前端和后端功能合并到一个配置块中,淘汰了配置文件的复杂性,特别适合不需要复杂路由规则的负载平衡场景。
- 对于简朴场景,利用listen可以简化配置,不需要复杂的前端规则
- 对于复杂路由规则,仍建议利用分开的frontend和backend
listen语法结构- sudo tee /etc/rsyslog.d/haproxy.conf <<-EOF
- \$ModLoad imudp
- \$UDPServerRun 514
- local2.* /var/log/haproxy.log
- EOF
复制代码 例子:- #将 /etc/sysconfig/rsyslog 文件中的文件中的的配置为: SYSLOGD_OPTIONS="-c 2 -r -m 0"
- sudo sed -i '/SYSLOGD_OPTION/c\SYSLOGD_OPTIONS="-c 2 -r -m 0"' /etc/sysconfig/rsyslog
复制代码 3.6 负载平衡调度算法
HAProxy负载平衡调度算法可以在HAProxy配置文件中设定。支持配置多组后端服务组,每个组可以分别指定一种调度算法。以下是HAProxy支持的几种调度算法。
在 HAProxy 中,负载平衡算法可以分为 动态(Dynamic) 和 静态(Static) 两大类,主要区别在于是否实时考虑后端服务器的状态(如连接数、响应时间等)。以下是分类说明及典型利用场景:
- 静态调度算法
静态算法在分配请求时 不实时考虑后端服务器的当前负载状态,仅根据预设规则(如权重、哈希值)进行分发。
算法名称原理适用场景roundrobin(轮询,默认算法)按顺序依次将请求分发到后端服务器,循环往复。支持权重的运行时调整,支持慢启动(在刚启动时缓慢接收大量请求),仅支持最大4095个后端活动主机。后端服务器性能匀称,且无长连接影响。static-rr(加权轮询)类似 Round Robin,但支持为服务器分配权重(weight),权重高的服务器得到更多请求。服务器性能不同等时,通过权重分配流量。source(源地址哈希)根据客户端源 IP 的哈希值分配服务器,同源 IP 地址的请求固定分配到同一台服务器。需要会话保持(Session Persistence)的场景(如用户登录状态)。uri(URI 哈希)根据请求 URI 路径的哈希值分配服务器,相同 URI 的请求固定分配到同一台服务器。缓存优化(同一 URI 由同一服务器处理,提高缓存命中率)或需要固定 URI 到特定服务器的场景。url_param(URL 参数哈希)根据 URL 中的特定参数(如 ?session_id=xxx)哈希分配。(如果指定的参数没有值,则回退到轮询)需要基于特定参数保持会话(如用户 ID,保证同一用户ID的请求分配至同一服务节点)。first(初次可用)按服务器在列表中的顺序分配请求,直到服务器达到最大连接数后再切换到下一台。需要严格优先利用某台服务器的场景(如备份服务器)适合会话保持、缓存优化或服务器性能匀称的场景。比方:source(会话保持)、uri(缓存优化)、static-rr(权重分配)。
- 动态调度算法
动态算法会 实时考虑后端服务器的状态(如连接数、响应时间等),动态调整流量分配。
算法名称原理适用场景leastconn(最少连接)优先将请求分配给当前连接数最少的服务器(可共同权重利用)。长连接或会话耗时差异较大的场景(如数据库、文件传输)。hdr(HTTP头哈希)根据客户端请求中的 特定 HTTP 头字段(Header) 计算哈希值,并将请求固定分配到同一台后端服务器。(如果指定的头字段不存在,则回退到轮询)需要主动规避高延迟或故障节点,优先选择响应快的服务器(如金融交易体系)。random(随机分配)随机选择(可共同权重利用),但结合服务器状态(如康健查抄)调整。后端服务器数量多且性能靠近。适合长连接、请求处理时间差异大或需主动容错的场景。比方:leastconn(数据库)、hdr(高可用 API)。
选择建议
- 会话保持:source、uri、url_param。
- 性能平衡:leastconn、static-rr。
- 简朴公平:roundrobin、random。
- 动态调整:基于响应时间的算法。
根据实际业务需求(如会话、性能、缓存)和服务器特性(如权重、连接数)选择合适的算法。
3.6.1 hdr 负载平衡算法详解
hdr 是 HAProxy 中的一种 动态负载平衡算法,它基于 HTTP 请求头(Header) 的内容进行流量分发,常用于高级路由和会话保持场景。以下是具体说明:
- 算法原理
作用:根据客户端请求中的 特定 HTTP 头字段(Header) 计算哈希值,并将请求固定分配到同一台后端服务器。
核心机制:
- 提取指定的 HTTP 头(如 X-User-ID、Cookie 等)。
- 对头字段的值进行哈希计算,映射到后端服务器。
- 相同头值 → 同一服务器,实现会话保持(Session Persistence)。
- 配置语法
- sudo systemctl restart rsyslog.service
- sudo systemctl restart haproxy.service
复制代码
- :要哈希的 HTTP 头字段(如 Cookie、X-Forwarded-For)。
- use_domain_only(可选):仅对头字段中的域名部分哈希(适用于 Host 头)。
示例配置 - 核心特性与利用场景
- (1)会话保持(Session Persistence):相同 HTTP 头值的请求始终分配到同一台服务器,如:
- 需要保持用户登录状态(如基于 Cookie)。
- 确保同一用户的请求由同一服务器处理(如购物车、游戏会话)。
- (2)机动的路由控制:可基于恣意 HTTP 头字段(如 User-Agent、Authorization)进行路由。
- 示例:将移动端流量(User-Agent 包含 Mobile)导向特定服务器组。
- (3)动态哈希调整:后端服务器增减时,HAProxy 会主动重新计算哈希分布(类似同等性哈希)。
- bind *:80 #监听所有IP的 80端口(不推荐,可能同时监听 IPv4 和 IPv6,不同版本兼容不一样)
- bind 0.0.0.0:80 #监听所有 IPv4 地址
- bind [::]:80 #监听所有 IPv6 地址
- bind :::80 v6only off #同时监听IPv4和IPv6
- bind 192.168.1.100:443 ssl crt /etc/haproxy/cert.pem #监听带SSL证书的HTTPS
复制代码 - 注意事项
- (1)HTTP 头必须存在
- 如果指定的头字段不存在,HAProxy 会 回退到轮询(Round Robin)。
- 办理方案:利用 hdr_reg(正则匹配)或结合 ACL 规则确保头字段有用。
- (2)哈希冲突问题
- 不同头值大概哈希到同一台服务器(概率低)。
- 办理方案:增长后端服务器数量或调整哈希算法(如同等性哈希)。
- (2)性能开销
- 计算哈希比静态算法(如 roundrobin)略高,但影响可忽略。
- 对比其他会话保持算法
算法依据适用场景机动性hdr恣意 HTTP 头字段需要精致路由或会话保持⭐⭐⭐⭐source客户端源 IP简朴 IP 级会话保持⭐⭐uri请求 URI 路径缓存优化(如 CDN)⭐⭐⭐url_paramURL 查询参数(如 ?id=)基于参数的路由⭐⭐⭐
总结
hdr 的核心价值:通过 HTTP 头实现 机动的路由控制和会话保持,适合需要精致流量管理的场景。
推荐利用场景:
- 基于用户身份(如 Cookie、JWT)的会话保持。
- 多租户或 API 网关的流量隔离。
- 需要动态哈希调整的高可用架构。
3.7 康健查抄(Health Check)
HAProxy 的康健查抄(Health Check)是确保后端服务器(Backend Server)可用性的关键机制,通过定期检测服务器状态,主动将故障节点从负载平衡池中移除或重新加入。常见的康健查抄类型包括TCP连接查抄、HTTP请求查抄等。
- 康健查抄类型
- acl <acl_name> <criterion> [flags] [operator] [value] ...
- #定义一条ACL,ACL是根据数据包的指定属性条件,以指定表达式计算出的 true/false 值。如:
- acl url_ms1 path_beg -i /ms1/
- #定义了名为 url_ms1 的ACL,该ACL在请求uri中,以/ms1/开头的路径(-i忽略大小写)时为 true
复制代码 - 高级康健查抄选项
- frontend http_in
- #disabled #禁用前端 http_in
- bind *:80
- #条件性禁用:disabled + acl
- #当访问路径以 /maintenance 开头时,禁用整个前端
- #acl maintenance_mode path_beg /maintenance
- #disabled if maintenance_mode
- #disabled if { file(/etc/haproxy/maintenance.flag) -m found }
- #示例1:基于主机名的路由
- acl host_web hdr(host) -i example.com #请求头部头部的 host 精确匹配 example.com
- use_backend web_servers if host_web
- use_backend api_servers if { hdr(host) -i api.example.com }
- #示例2:基于URL路径的路由
- acl path_images path_beg -i /images/ #请求路径以 /images/ 开始
- use_backend image_servers if path_images
- #示例3:基于HTTP方法的复杂条件
- acl is_get method GET #get请求方式
- acl is_post method POST #post请求方式
- acl is_admin path_beg /admin/ #请求路径以 /admin/ 开始
- acl valid_user hdr(X-User-Id) -m found #请求头部的 X-User-Id 完全匹配 found
- use_backend admin_servers if is_admin valid_user
- use_backend readonly_servers if is_get !is_admin
- use_backend write_servers if is_post !is_admin
- #示例4:基于源IP的路由
- acl internal_network src 192.168.1.0/24 #匹配源IP地址
- acl vpn_network src 10.0.0.0/8
- use_backend internal_servers if internal_network
- use_backend vpn_servers if vpn_network
- #默认后端
- default_backend default_servers
- backend web_servers
- backend api_servers
- ...
- backend default_servers
复制代码 - 监控与管理
- (1)日志记载
康健查抄日志需在 HAProxy 配置中启用:
log 127.0.0.1 local0 notice
- (2)查看康健状态
- # 禁用前端
- echo "disable frontend http_front" | sudo socat stdio /var/run/haproxy/admin.sock
- # 启用前端
- echo "enable frontend http_front" | sudo socat stdio /var/run/haproxy/admin.sock
- # 查看状态
- echo "show stat" | sudo socat stdio /var/run/haproxy/admin.sock | grep http_front
复制代码 访问 http://:9000/haproxy_stats 查看服务器状态(颜色标记康健/故障)。
- 常见问题
- (1)误判(Flapping),如:服务器频仍被标记为故障又恢复。
- 办理:调整 rise 和 fall 参数,增长检测稳定性。
- (2)查抄路径不可达,如:HTTP 查抄返回 404。
- 办理:确保后端服务器提供正确的康健查抄端点(如 /health)。
- (3)超时设置:调整超时时间制止误判
最佳实践
- 轻量级查抄:利用专用低开销的查抄端点(如 /health)。
- 隔离查抄流量:制止康健查抄影响业务流量。
- 结合容器化情况:在 Kubernetes/Docker 中,查抄需兼容动态 IP 变化。
通过合理配置康健查抄,HAProxy 可以显著提高服务的可靠性和容错能力。根据实际需求选择 TCP/HTTP 查抄,并机动调整参数以优化性能。
四、实例
- frontend http-in
- bind *:80
- bind *:443 ssl crt /etc/ssl/certs/mydomain.pem
- #示例1:HTTP到HTTPS重定向
- redirect scheme https code 301 if !{ ssl_fc }
- #示例2:路径重定向
- redirect prefix /new/path code 301 if { path_beg /old/path/ }
- #示例3:域名重定向
- acl is_old_domain hdr(host) -i old.example.com
- redirect prefix http://new.example.com code 301 if is_old_domain
- #redirect prefix http://new.example.com code 301 if { hdr(host) -i old.example.com }
- #示例4:域名重定向是否“保留路径”,原始请求:http://old.example.com/path/to/resource
- #prefix - 保留路径,只重置协议和域名,重定向到:https://new.example.com/path/to/resource
- redirect prefix https://new.example.com code 301 if { hdr(host) -i old.example.com }
- #location - 丢弃路径,完全替换 URL,重定向到:https://new.example.com (丢失了原始路径)
- redirect location https://new.example.com code 301 if { hdr(host) -i old.example.com }
- #示例5:重定向是否保留参数,原始请求:http://example.com/old/path/?search=hello
- #不使用 drop-query(默认),重定向到:http://example.com/new/path/?search=hello
- redirect prefix /new/path code 301 if { path_beg /old/path/ }
- #使用 drop-query,重定向到:http://example.com/new/path(?search=hello 被丢弃)
- redirect prefix /new/path drop-query code 301 if { path_beg /old/path/ }
- #示例6:添加尾部斜杠
- redirect append-slash if { path_reg ^/path[^/]*$ }
- #示例7:带条件的重定向
- acl is_mobile hdr(User-Agent) -i -m reg (android|iphone|ipad)
- redirect prefix http://m.example.com code 302 if is_mobile
复制代码
Via
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |