HAProxy系列文章一《什么是HAProxy》

发布于:2024-05-16 ⋅ 阅读:(71) ⋅ 点赞:(0)

瀚高数据库
目录
文档用途
详细信息

文档用途
本文主要介绍什么是HAProxy,HAProxy的工作原理以及部分配置参数详解。本文为HAProxy系列文章之一,其他相关文章请点击文档下方的相关文档链接进行详细查看,文章内不在赘述。

详细信息

一、HAProxy简介

以下内容均翻译自HAProxy官网。

1、什么是HAProxy
HAProxy是一种免费、非常快速且可靠的反向代理,可为基于TCP和HTTP的应用程序提供高可用性、 负载平衡和代理。它特别适用于流量非常大的网站,并为世界上访问量最大的网站中的很大一部分提供支持。多年来,它已成为事实上的标准开源负载均衡器,现在随大多数主流Linux发行版一起提供,并且通常默认部署在云平台中。由于它不为自己做广告,我们只有在管理员报告时才知道它被使用了
HAProxy核心团队并行维护多个版本。从1.8版本开始,每年发布两个主要版本。第一个数字通常表示重大更改(配置格式等),但实际上很少更改。第二位数字表示新功能。两者构成一个分支。这些数字后面会出现一个额外的数字,表示错误修复版本。
偶数号的分支称为“LTS”(“长期支持”),区域在发布后保留5年。在此期间,他们将收到对发布后发现的错误的修复。这些分支针对的是一般用户,他们寻求极度的稳定性并且不想过于频繁地验证新版本但仍希望获得修复。
奇数分支仅称为“稳定”,它们针对的是高技能用户,他们喜欢经常升级以从现代功能中受益,并且在出现问题时也能够回滚。这些版本的维护时间为12到18个月。持续时间很短并且故意不严格,以便根据反馈与用户一起决定维护周期,并且这些版本不会最终出现在嵌入式产品中。如果有一些合理的需求并且该操作被认为足够无风险,则可能会向后移植一些功能到这些版本。
截止笔者编辑时,HAProxy的最新版本为2.7版本。

2、HAProxy是怎么工作的
HAProxy是一个事件驱动的非阻塞引擎,结合了非常快速的I/O层使用基于优先级的多线程调度程序。因为它是用数据设计的牢记转发目标,其架构经过优化以尽可能快地移动数据尽可能少的操作。它专注于优化CPU通过尽可能长时间地将连接连接到同一个CPU来提高缓存的效率。因此,它实现了分层模型,在每个级别提供旁路机制除非需要,否则确保数据不会达到更高级别。大部分加工在内核中执行,HAProxy 尽最大努力帮助内核完成通过给出一些提示或避免某些操作来尽快工作当它猜测它们可以稍后分组时。因此,典型数字显示15% 的处理时间花在HAProxy 上,而85%的处理时间花在TCP或内核上HTTP关闭模式,大约30%用于HAProxy,而70%用于HTTP内核保持活动模式。
同多进程或多线程模型相比,此类模型的优点在于能够支撑高并发大规模的连接。因为多进程或多线程模型受内存和系统调度器的限制以及无处不在的锁限制,因此很难应对数以万计的高并发连接。

一旦HAProxy启动,它就会做3件事:
-处理传入连接;
-定期检查服务器的状态(称为健康检查);
-与其他 HAPROXY 节点交换信息。

处理传入连接是迄今为止最复杂的任务,因为它取决于许多配置可能性,但可以总结为下面9个步骤
-接受来自侦听套接字的传入连接,这些连接属于称为“前端”的配置实体,该实体引用一个或多个侦听地址;
-将特定于前端的处理规则应用于这些连接,这可能会导致阻塞它们、修改某些标头或拦截它们以执行某些内部小程序,例如统计信息页面或 CLI;
-将这些传入连接传递到表示称为“后端”的服务器场的另一个配置实体,该实体包含服务器列表和此服务器场的负载平衡策略;
-将特定于后端的处理规则应用于这些连接;
-根据负载平衡策略决定将连接转发到哪个服务器;
-将特定于后端的处理规则应用于响应数据;
-将特定于前端的处理规则应用于响应数据;
-发出日志以详细报告发生的事情;
-在 HTTP 中,循环回第二步以等待新请求,否则关闭连接。

3、基本功能
HAproxy提供代理、SSL、监控、高可用、负载均衡等很多功能特性,其中代理跟负载均衡功能是我们DBA岗位最关注的特性,后续的文章也围绕代理、负载均衡部分进行介绍。HAProxy 提供了一套相当完整的负载均衡功能,其中大部分功能是其他许多其他负载平衡产品不具备的。

代理
代理是通过两个独立的连接在客户机和服务器之间传输数据的操作。HAProxy 在代理和连接管理方面支持以下基本功能:
-为服务器提供干净的连接,以保护它们免受任何客户端缺陷或攻击;
-侦听多个IP地址和/或端口,甚至端口范围;
-透明接受:拦截针对任何甚至不属于本地系统的任意IP地址的流量;
-服务器端口不需要与侦听端口相关,甚至可以通过固定偏移量进行转换(对范围有用);
-透明连接:如果需要,在连接到服务器时欺骗客户端(或任何)的IP地址;
-为多站点LBs的服务器提供可靠的返回IP地址;
-由于缓冲区和可能的短期连接,卸载服务器,以减少其并发连接计数和内存占用;
-优化 TCP 堆栈(例如 SACK)、拥塞控制并减少 RTT 影响;
-支持两端不同的协议系列(例如IPv4 / IPv6 / Unix);
-超时强制:HAProxy支持多个级别的超时,这取决于连接的阶段,所以一个死客户端或服务器,或攻击者不能被授予资源太长时间;
-协议验证:检查HTTP,SSL或有效负载并拒绝无效的协议元素,除非指示接受它们;
-政策执行:确保只能转发允许的内容;
-传入和传出连接可能仅限于某些网络命名空间(仅限 Linux),从而可以轻松构建跨容器、多租户负载均衡器;
-PROXY 协议向服务器提供客户端的 IP 地址,即使对于非 HTTP 流量也是如此。这是一个HAProxy扩展,现在已经被许多第三方产品采用,至少在撰写本文时是这样:
-客户端:haproxy, stud, stunnel, exaproxy, ELB, squid
-服务器:haproxy, stud, postfix, exim, nginx, squid, node.js, varnish

负载均衡

-支持不少于10种负载均衡算法,其中一些适用输入数据以提供无限的可能性。最常见的是round-robin(对于短连接,轮番选择每个服务器),leastconn(对于长连接,选择最少连接且最近最少使用的服务器),source (对于SSL群或终端服务器群,服务器直接依赖于客户端的源地址),URI(对于HTTP缓存,服务器直接依赖于HTTP URI),hdr(服务器直接取决于特定 HTTP 标头字段的内容),first(对于短期存活的虚拟机,所有连接都打包尽可能小的服务器子集,这样就可以关闭未使用的服务器);
-上述所有算法都支持每台服务器的权重,因此可以容纳服务器场中不同世代的服务器,或将一小部分流量定向到特定服务器(调试模式、运行下一版本的软件等)
-支持动态权重用于round-robin(轮询)、leastconn(最小连接 )和consistent hashing(一致哈希);这允许从 CLI 甚至由服务器上运行的代理动态修改服务器权重;
-只要支持动态权重,就支持慢启动;这允许服务器逐步获取流量。对于需要在运行时编译类的脆弱应用程序服务器以及需要在全速运行之前填满的冷缓存,这是一个重要的功能;
-哈希可以应用于各种元素,如客户端源地址、URL组件、查询字符串元素、报头字段值、POST参数、RDP cookie;
-在服务器场中添加或删除服务器时,一致性哈希可防止服务器场进行大规模重新分发。这在大型缓存场中非常重要,它允许使用慢启动来重新填充冷缓存;
-许多内部指标,如每个服务器、每个后端连接的数量、后端可用连接槽的数量等,使构建非常高级的负载平衡策略成为可能。

二、参数介绍

HAProxy因功能强大,涉及到的参数也非常众多,根据官方文档的划分,共分为5大类、其中仅global参数一项就分为76个参数,在此我们仅介绍同数据库负载均衡相关的一些参数,并且根据配置文件的格式进行划分介绍。

HAProxy的配置文件主要分为五个部分,即global(全局功能配置)、defalults(默认属性配置)、frontend(前端代理配置)、backend(后端配置),listen(监控配置)5个部分,其中后4部分为代理配置的一系列设置模块。

global:参数是进程级的,通常和操作系统(OS)相关。这些参数一般只设置一次,如果配置无误,就不需要再次配置进行修改
defaults:配置默认参数的,这些参数可以被利用配置到frontend,backend,listen组件
frontend:描述了一组接受客户端连接的监听套接字。接收请求的前端虚拟节点,Frontend可以根据规则直接指定具体使用后端的backend(可动态选择)。
backend:描述了一组服务器,代理将连接到这些服务器以转发传入连接。后端服务集群的配置,是真实的服务器,一个Backend对应一个或者多个实体服务器。
listen:定义了一个完整的代理,其前端和后端部分组合在一个部分中。它通常对纯 TCP 流量有用。Frontend和Backend的组合体。

下面我们介绍部分数据库使用HAproxy时可能用到的配置参数,详见下文。

1、global
-chroot:修改haproxy的工作目录至指定的目录并在放弃权限之前执行chroot()操作,可以提升haproxy的安全级别,不过需要注意的是要确保指定的目录为空目录且任何用户均不能有写权限;

-daemon:让haproxy以守护进程的方式工作于后台,其等同于“-D”选项的功能,当然,也可以在命令行中以“-db”选项将其禁用;
-gid :以指定的GID运行haproxy,建议使用专用于运行haproxy的GID,以免因权限问题带来风险;
-group :同gid,不过指定的组名;
-log

[max level [min level]]:定义全局的syslog服务器,最多可以定义两个;
-log-send-hostname []:在syslog信息的首部添加当前主机名,可以为“string”指定的名称,也可以缺省使用当前主机名;
-nbproc :指定启动的haproxy进程的个数,只能用于守护进程模式的haproxy;默认只启动一个进程,鉴于调试困难等多方面的原因,一般只在单进程仅能打开少数文件描述符的场景中才使用多进程模式;
-pidfile:
-uid:以指定的UID身份运行haproxy进程;
-ulimit-n:设定每进程所能够打开的最大文件描述符数目,默认情况下其会自动进行计算,因此不推荐修改此选项;Linux默认单进程打开文件数为1024个
-user:同uid,但使用的是用户名;
-node:定义当前节点的名称,用于HA场景中多haproxy进程共享同一个IP地址时;
-description:当前实例的描述信息;
-maxconn :设定每个haproxy进程所接受的最大并发连接数,其等同于命令行选项“-n”;“ulimit -n”自动计算的结果正是参照此参数设定的;
-maxpipes :haproxy使用pipe完成基于内核的tcp报文重组,此选项则用于设定每进程所允许使用的最大pipe个数;每个pipe会打开两个文件描述符,因此,“ulimit -n”自动计算时会根据需要调大此值;默认为maxconn/4,其通常会显得过大;
-timeout http request :在客户端建立连接但不请求数据时,关闭客户端连接
-timeout queue :等待最大时长
-timeout connect: 定义haproxy将客户端请求转发至后端服务器所等待的超时时长
-timeout client:客户端非活动状态的超时时长
-timeout server:客户端与服务器端建立连接后,等待服务器端的超时时长,
-timeout http-keep-alive :定义保持连接的超时时长
-timeout check:健康状态监测时的超时时间,过短会误判,过长资源消耗
-maxconn :每个server最大的连接数
-http-server-close : 在使用长连接时,为了避免客户端超时没有关闭长连接,此功能可以使服务器端关闭长连接
-redispatch: 在使用基于cookie定向时,一旦后端某一server宕机时,会将会话重新定向至某一上游服务器,必须使用的选项

2、代理功能涉及重点参数

摘自官网相应的关键字设置矩阵,适用于defaults、frontend、backend、listen等部分,部分参数在global中已说明。

-balance:定义在后端使用的负载平衡算法,支持roundrobin、static-rr,leastconn、first等11种算法。

balance <algorithm> [ <arguments> ]

-bind:定义一个活一些列前端的监听地址和/或端口。

bind [<address>]:<port_range> [, ...] [param*]
bind /<path> [, ...] [param*]

-default-server:更改后端服务器的默认选项

default-server[param*]

-default_backend: 指定当没有匹配“使用后端”规则时要使用的后端

default_backend<backend>

-enabled:启用前端或后端的代理

-hash-type:指定用于将哈希映射到服务器的方法

hash-type <method> <function> <modifier>

-http-after-response:有第 7 层响应(服务器、小程序/服务和内部响应)的访问控制。http-after-response 语句定义了一组适用于第 7 层处理的规则。 当在前端、侦听或后端部分满足规则时,规则将按照它们的声明顺序进行评估。

http-after-response <action> <options...> [ { if | unless } <condition> ]

-http-check comment:为 http-check 规则定义注释,如果失败则在日志中报告。

http-check comment <string>

-http-check connect: 打开一个新连接以执行 HTTP 健康检查。

http-check connect [default] [port <expr>] [addr <ip>] [send-proxy]
                   [via-socks4] [ssl] [sni <sni>] [alpn <alpn>] [linger]
                   [proto <name>] [comment <msg>]

-http-check expect 使HTTP运行状况检查考虑响应内容或特定的状态代码

http-check expect [min-recv <int>] [comment <msg>]
                  [ok-status <st>] [error-status <st>] [tout-status <st>]
                  [on-success <fmt>] [on-error <fmt>] [status-code <expr>]
                  [!] <match> <pattern>

-http-check send:向 HTTP 健康检查期间发送的请求添加可能的标头列表和/或正文。

http-check send [meth <method>] [{ uri <uri> | uri-lf <fmt> }>] [ver <version>]
                [hdr <name> <fmt>]* [{ body <string> | body-lf <fmt> }]
                [comment <msg>]

-http-check send-state: 启用发送带有HTTP运行状况检查的状态标头

-http-error status:定义一个自定义错误消息来代替HAProxy生成的错误。

http-error status <code> [content-type <type>]
           [ { default-errorfiles | errorfile <file> | errorfiles <name> |
               file <file> | lf-file <file> | string <str> | lf-string <fmt> } ]
           [ hdr <name> <fmt> ]*

-http-request:http-request语句定义了一组适用于第 7 层处理的规则。 当在前端、侦听或后端部分满足规则时,规则将按照它们的声明顺序进行评估。

http-request <action> [options...] [ { if | unless } <condition> ]

-http-response:http-response 语句定义了一组适用于第 7 层处理的规则。 当在前端、侦听或后端部分满足规则时,规则将按照它们的声明顺序进行评估。

http-response <action> <options...> [ { if | unless } <condition> ]

-log:启用事件和流量的每个实例日志记录。

log global
log <address> [len <length>] [format <format>] [sample <ranges>:<sample_size>] <facility> [<level> [<minlevel>]]
no log

-log-format:指定用于流量日志的日志格式字符串

log-format <string>

-maxconn:定义前端最大并发连接数

maxconn <conns>

-mode:设置HAProxy实例默认的运行模式,有tcp, http, 两个可选值

mode { tcp|http }

tcp模式:

实例会工作在纯TCP模式下,客户端和服务器端间将建立一个全双工的连接,不会对七层报文做任何检查,这是默认的模式;经常用于SSL, SSH, SMTP等
http模式
实例会工作在HTTP 模式下,客户端请求在转发至后端服务器前将会被深度分析,任何不符合RFC标准的请求都会被拒绝。第七层协议的过滤、处理及切换都是可能的,这是实现HAProxy绝大部分价值的模式。

-option tcplog:启用带有会话状态和计时器的TCP连接高级日志记录

-option http-server-close:在服务器端启用或禁用HTTP连接关闭

option http-server-close
no option http-server-close

-option redispatch:当连接失败时,启用或禁用会话重分发

option redispatch
option redispatch <interval>
no option redispatch

retries:设置当服务器故障后最大的重新尝试连接次数。

retries <value>

-retry on: 指定何时尝试自动重试失败的请求。此设置仅在“mode”设置为http时有效,否则将被静默忽略。

retry-on [space-delimited list of keywords]

-server 在后端声明一个服务器

server <name> <address>[:[port]] [param*]

-stats admin 如果/除非条件匹配,启用统计admin级别

stats admin { if | unless } <cond>

-stats auth 启用带有身份验证的统计信息并授予对帐户的访问权
stats auth :

-stats enable: 使用默认设置启用统计报告

-stats hide-version: 启用统计和隐藏HAProxy版本报告

-stats http-request: 统计访问控制

stats http-request { allow | deny | auth [realm <realm>] }
             [ { if | unless } <condition> ]

-stats realm: 开启统计并设置认证域
stats realm

-stats refresh: 使用自动刷新启用统计信息
stats refresh

-stats scope: 启用统计信息并限制访问范围
stats scope { | “.” }

-stats show-desc: 在统计页面上启用描述的报告。

stats show-desc [ <desc> ]

-stats show-legends: 启用在统计信息页面上报告附加信息

-stats show-node: 在统计页面中启用主机名上报功能。

stats show-node [ <name> ]

-stats uri 启用统计信息并定义访问它们的URI前缀

stats uri <prefix>

-timeout check:设置额外的检查超时,但仅在已建立连接之后

timeout check <timeout>

-timeout client:在客户端设置最大不活动时间

timeout client <timeout>

-timeout connect :设置等待连接尝试成功的最大时间。

timeout connect <timeout>

-timeout http-keep-alive:设置等待新HTTP请求出现的最大允许时间

timeout http-keep-alive <timeout>

-timeout http-request :设置等待一个完整HTTP请求的最大允许时间

timeout http-request <timeout>

-timeout queue:设置在队列中等待连接槽空闲的最大时间

timeout queue <timeout>

-timeout server:在服务器端设置最大不活动时间

timeout server <timeout>