github:https://github.com/haproxy/haproxy/blob/master/doc/intro.txt
date:2020-06
HAProxy不是:
- 一个显式HTTP代理
- 数据清洗机
- 静态Web服务器
- 基于数据包的负载均衡器
HAProxy 是一个事件驱动的、非阻塞的引擎,包含了一个基于优先级的多线程调度器的非常快的I/O层。它的设计考虑到了数据转发的目标,它的架构优化了数据移动操作,并尽可能以最少的操作完成数据移动。它通过让连接尽可能久的与相同的CPU保持连接来专门优化CPU缓存的效率。同样它实现了一个分层模型,在每一级别提供旁路机制
[1],确保非必须的情况下数据达不到更高的级别。绝大多数的处理都被放到了内核中执行,并且HAProxy在协助内核尽可能快的作业方面做到了最好,HAProxy通过向内核给出提示或在猜测可以稍后分组时直接避免某些操作。有效的数据表明,HAProxy和内核在TCP或HTTP关闭模式下的处理时间占比分别为15%和85%,而在HTTP保持活动模式下,HAProxy的处理时间约为30%,内核的处理时间为70%。
[1] 旁路机制:ByPass Mode(略过模式或旁路模式),泛指在一个系统的正常流程中,有一堆检核机制,而“ByPass Mode”就是当检核机制发生异常,无法在短期间内排除时,使系统作业能绕过这些检核机制,使系统能够继续运行的作业模式。例如,在收费(月费或点数卡)的线上游戏中,当游戏官方要赔偿玩家的游戏时数时,可以在特定时间内打开“ByPass Mode”,使游戏的登录机制绕过月费或点数卡的余额检核机制。使仍在使用中的游戏账号,可以免扣点数或游戏天数而登录进线上游戏之中。
单个进程可以运行许多代理实例,研究表示就算配置30W个的不同代理的情况下,一个进程也能运行的很好。对于超过99%的用户来说,单核心、单CPU的设置是远远不够的,正因如此,鼓励容器和虚拟机的用户使用尽可能小的图像,以节省操作成本并简化故障排查。然而,HAProxy运行的机器绝不能掉换,它的cpu绝不能人为地节流(管理程序中的子CPU分配),也不能与计算密集型进程共享,这会导致非常高的上下文切换延迟。
允许通过每个CPU核心使用一个线程来利用所有可用的处理能力。这对于SSL或需要超过40 Gbps的数据转发速率来说非常有用。在这种情况下避免多个物理CPU之间的通信至关重要,否则可能会在网络堆栈和HAProxy自身造成巨大的瓶颈。当遇到性能问题时,首先要做的事情通常是减少运行HAProxy的cpu数量。
HAProxy只需要运行haxy可执行文件和配置文件。对于日志记录,强烈建议设置一个正确配置的syslog守护进程和日志轮转(切割)。日志也可以发送到stdout/stderr(标准输出设备/标准错误输出设备),这样在容器内部是非常有用的。在启动前对配置文件进行解析,然后HAProxy尝试绑定所有监听sockets,如果有任何失败,则拒绝启动。过了这一步,它就不能再失败了。这意味着没有运行时失败,如果它接受启动,它将工作直到它被停止。
一旦HAProxy启动了,它就会做这3件事:
处理传入连接是迄今为止最复杂的任务,因为它取决于许多配置可能性。但是它可以总结为以下9个步骤:
前端和后端有时被认为是半代理,因为他们只看端到端连接的一侧;前端只关心客户端,后端只关心服务器。HAProxy还支持完整的代理,正是前端和后端的结合。当需要HTTP处理时,配置通常会被分割成前端和后端,因为他们有很多可能性:任何前端可能传递一个连接到任何后端。对于只使用tcp代理的代理,使用前端和后端几乎没有什么好处,而使用完整代理的配置会更容易读懂。
代理是通过两个独立连接在客户机和服务器之间传输数据的操作。以下是HAProxy支持的关于代理和连接管理的基本特性:
根据谷歌工程师的说法,HAProxy的SSL协议栈被认为是最具特色的协议之一(http://istlsfastyet.com/)。最常用的特性有:
HAProxy 非常关注可用性。因此它关心服务器状态,以及向其他网络组件报告自己的状态:
就像任何严重的负载均衡器一样,HAProxy非常关心可用性,以确保最佳的全局服务连续性:
HAProxy提供了一套相当完整的负载平衡功能,不幸的是,其中大多数特性在许多其他负载平衡产品中是不可用的。
如果没有粘性,应用程序负载平衡将是无用的。HAProxy提供了一组相当全面的可能性,可以在同一服务器上维护访问者,即使跨越各种事件,如服务器添加/删除、下行/上行周期,而且有些方法的设计是为了抵抗多个负载平衡节点之间的距离,因为它们不需要任何复制:
HAProxy支持使用一组广泛的“样本获取函数”进行信息采样。其原则是提取被称为样本的信息片段,以便立即使用。它用于粘性、构建条件、在日志中生成信息或丰富HTTP头。
可以从各种来源获取样品:
然后,一个示例可能会通过许多名为“转换器”的操作符来进行一些转换。转换器使用一个示例并产生一个新的样本,可能是完全不同的类型。例如,转换器可以仅用于返回输入字符串的整数长度,或者可以将字符串转换为大写。在最终使用之前,可以将任意数目的转换器串联应用于样品。在所有可用的示例转换器中,以下是最常用的:
Maps是一种强大的转换器类型,包括在启动时将两列文件加载到内存中,然后从第一列中查找每个输入示例,如果找到条目,则在第二列上返回相应的模式,或者返回默认值。输出信息也是一个示例,它反过来可以体验其他转换,包括其他映射查找。映射通常用于将客户端的IP地址转换为AS号码或国家代码,因为它们支持最长的网络地址匹配,不过它们可用于其他各种用途。
它们的部分优势来自于可以动态更新的CLI或使用其他示例的某些操作,从而使它们能够在后续访问之间存储和检索信息。另一个优势来自基于二叉树的指数化,即使它们包含了数十万个条目,它也使它们非常快,使得地理定位非常便宜和易于设置。
HAProxy中的大多数操作都是有条件的。条件是通过使用逻辑运算符(AND,OR,NOT)组合多个ACL
[2]来构建的。每个ACL都是基于以下元素的一系列测试:
[2] 访问控制列表(Access Control Lists , 英文缩写 ACL)是一种基于包过滤的访问控制技术,它可以根据设定的条件对接口上的数据包进行过滤,允许其通过或丢弃。访问控制列表被广泛地应用于路由器和三层交换机,借助于访问控制列表,可以有效地控制用户对网络的访问,从而最大程度地保障网络安全。
例如,可以从HTTP “Host” 头中获取,然后可以转换为小写,然后使用regex匹配方法与许多regex模式进行匹配。
技术上,ACL与map建立在同一个核心上,它们有着完全相同的内部结构、模式匹配方法和性能。唯一真正的区别是没有返回一个样本,他们只返回“找到”或“找不到”。在使用方面,可以在配置文件中内联声明ACL模式,而不需要自己的文件。ACL的命名可能是为了便于使用或使配置易于理解。一个命名的ACL可以被多次声明,它将依次评估所有定义,直到一个匹配为止。
提供了13种不同的模式匹配方法,其中IP地址掩码、整数范围、子串、正则表达式。它们像函数一样工作,就像任何编程语言一样,只计算所需的内容,因此,当涉及OR的条件已经为真时,下一个条件不进行计算,同样地,当涉及AND已经为false的条件时,则不计算条件的其余部分。
声明ACL的数量没有实际限制,并且提供了一些常用的ACL。然而,经验表明,使用大量命名ACL的设置很难排除故障,有时使用匿名ACL内联更容易,因为它需要更少的被分析范围之外的引用。
HAProxy实现了一种称为基于内容的交换机制。原则是连接或请求到达前端,然后处理该请求或连接所携带的信息,此时,可以编写基于ACL的条件,利用这些信息来决定哪个后端将处理请求。因此,基于请求的内容,通信量被定向到一个后端或另一个后端。最常见的示例是使用路径中的主机头和/或元素(子目录或文件扩展名)来决定HTTP请求是针对静态对象还是以应用程序为目标,并将静态对象流量路由到由快速和轻型服务器组成的后端,和所有剩余的流量到一个更复杂的应用服务器,从而构成一个细粒度的虚拟主机解决方案。这非常方便地使多种技术共存,成为一种更全面的解决方案。
内容交换的另一个用例是根据不同的标准使用不同的负载平衡算法。缓存可能使用URI哈希,而应用程序则使用轮询调度算法 (Round-Robin) 。
最后但并非最不重要的一点是,它允许多个客户通过强制每个后端(因此每个客户连接限制)来使用公共资源的一小部分。
内容切换规则具有很好的扩展性,尽管它们的性能可能取决于所使用的ACL的数量和复杂性。但是,还可以编写动态内容切换规则,其中示例值直接转换为后端名称,根本不使用ACL。据报道,这种配置在生产中至少可以与300000个后端一起工作。
Stick-tables 通常用于存储粘性信息,也就是说,为了保持对某个访问者所指向的服务器的引用。然后,密钥是与访问者关联的标识符(其源地址、连接的SSL ID、HTTP或RDP cookie、从URL或有效负载中提取的客户编号、……)而存储的值则是服务器的标识符。
Stick-tables可以使用3种不同类型的示例作为其键:整数、字符串和地址。在代理中只能引用一个stick-table,并且它在任何地方都被指定为代理名称。最多可并行跟踪8个键。一旦知道密钥和服务器,则在请求或响应处理期间提交服务器标识符。
Stick-table的内容可以在active-active模式下与其他HAProxy节点(称为“peers”)以及在重载操作期间与新进程复制,这样,如果客户端的请求分散在多个节点上,则所有负载平衡节点共享相同的信息并做出相同的路由决定。
由于Stick-table是根据允许识别客户端的内容编制索引的,因此它们通常也用于存储额外的信息,例如每个客户端的统计信息。额外的统计数据占用一些额外的空间,需要显式地声明。可以存储的统计数据类型包括输入和输出带宽、并发连接的数量、连接速率和周期计数、错误的数量和频率、一些特定的标记和计数器等。为了支持保存这样的信息,而不需要被迫固定在给定的服务器上,实现了一个特殊的“跟踪”功能,允许同时跟踪来自不同表的3个键,而不考虑粘性规则。可以从CLI中搜索、转储和清除每个存储的统计信息,并增加实时故障排除功能。
虽然这种机制可以用来超越返回的访问者,或者根据好的或坏的行为来调整交付的服务质量,但是它主要用于对抗服务滥用,更普遍地说是DDoS,因为它允许建立复杂的模型,以在较高的处理速度中检测某些不良行为。
在许多地方,HAProxy需要操作字符串,例如日志、重定向、头添加等等。为了提供最大的灵活性,引入了格式化字符串的概念,最初用于日志记录,这解释了为什么它仍然被称为“日志格式”。这些字符串包含转义字符,允许在字符串中引入各种动态数据(包括变量)和示例获取表达式,甚至在将结果转换为字符串时调整编码(例如,添加引号)。这提供了一种强大的方法来构建标题内容,构建响应数据,甚至响应模板,或者定制日志行。此外,为了保持构建大多数常见字符串的简单性,提供了大约50个特殊标记作为日志中常用信息的快捷方式。
如果没有适当的工具,在从未为此设计的应用程序前面安装负载均衡器可能是一项具有挑战性的任务。在这种情况下,最常见的请求操作之一是调整请求和响应头,使负载均衡器显示为源服务器,并修复硬编码信息。这包括更改请求中的路径(强烈建议不要)、修改主机标头字段、修改用于重定向的位置响应标头字段、修改cookie的路径和域属性等等。还会发生一些服务器有些冗长,往往会在响应中泄漏太多信息,使它们更容易受到目标攻击。虽然理论上它不是负载均衡器的作用,但实际上它位于基础设施中的最佳位置,以保证所有的东西都被清理干净。
类似地,有时负载均衡器将不得不拦截一些请求,并以重定向到新的目标URL来响应。虽然有些人倾向于混淆重定向和重写,但这是两个完全不同的概念,因为重写使客户端和服务器看到不同的东西(并且不同意所访问页面的位置),而重定向则要求客户端访问新的URL,这样它就可以看到与服务器相同的位置。
为了做到这一点,HAProxy支持重写和重定向的各种可能性,其中包括:
HAProxy为最大限度地提高服务可用性做了很多工作,为此,需要付出很大的努力来保护服务器免受超载和攻击。第一个也是最重要的一点是,只有完整和有效的请求才被转发到服务器。最初的原因是HAProxy需要找到它需要与字节流保持同步的协议元素,第二个原因是,在请求完成之前,无法知道某些元素是否会更改其语义。这样做的直接好处是服务器不会暴露于无效或不完整的请求中。这是一种非常有效的保护措施,防止了对HAProxy几乎没有影响的Slowloris攻击。
另一个重要的问题是,HAProxy包含用于存储请求和响应的缓冲区,并且只在请求完成时向服务器发送请求,并且通过从本地网络快速读取整个响应,服务器端连接将被使用很短的时间,这将尽可能地保留服务器资源。
对此的直接扩展是HAProxy可以人为地限制对服务器的并发连接或未决请求的数量,这保证了即使服务器在流量高峰期间连续以其容量的100%运行,也永远不会超载。当释放一个时隙时,所有多余的请求都将被排队处理。最后,这种巨大的资源节省通常确保了更好的服务器响应时间,最终实际上比重载服务器更快。排队的请求可能被重新发送到其他服务器,甚至在客户端中止时在队列中中止,这也保护服务器不受“重新加载”的影响,在这种情况下,慢加载页面上的访问者每次单击“重新加载”通常都会诱导一个新的请求,并将服务器保持在重载状态。
慢启动机制还保护重新启动服务器免受高流量的影响,同时它们仍在完成启动或编译某些类。
关于协议级别的保护,可以放松HTTP解析器以接受不符合标准但无害的请求或响应,甚至可以修复它们。这允许在开发修复程序时可以访问伪造的应用程序。同时,通过一份详细的报告来捕获违规消息,帮助开发人员发现应用程序中的问题。最危险的违反协议行为得到适当的发现、处理和修正。例如,格式错误的请求或带有两个内容长度标头的响应要么是固定的,如果值完全相同,要么被拒绝,如果它们不同,因为它成为一个安全问题。协议检查不仅限于HTTP,还可用于其他协议,如TLS或RDP。
当检测到协议违反或攻击时,有多种选项可对用户作出响应,例如返回常见的“HTTP 400错误请求”、用TCP重置关闭连接或在长时间延迟后假装错误(“tarpit”)以迷惑攻击者。所有这些都有助于保护服务器,阻止违规客户端进行维护成本非常昂贵的攻击。
HAProxy还提出了一些更高级的选项,以防止意外数据泄漏和会话交叉。它不仅可以记录可疑的服务器响应,还可以记录并选择性地阻止可能影响给定访问者的机密性的响应。其中一个例子是缓存响应中出现的可缓存cookie,它可能导致中间缓存将其传递给另一个访问者,从而导致意外的会话共享。
日志记录对于负载均衡器来说是一个极其重要的特性,首先是因为负载均衡器经常被错误地指责导致了它所揭示的问题,其次是因为它被放置在基础结构中的一个临界点,需要分析所有正常和异常的活动并将其与其他组件相关联。
HAProxy提供了非常详细的日志,具有毫秒的精度和在防火墙日志中可以搜索的准确连接接受时间(例如NAT相关性)。默认情况下,TCP和HTTP日志非常详细,并包含故障排除所需的所有内容,如源IP地址和端口、前端、后端、服务器、定时器(请求接收持续时间、队列持续时间、连接设置时间、响应头时间、数据传输时间)、全局进程状态、连接计数、队列状态、重试计数、详细的粘贴操作和断开原因、使用安全的输出编码捕获报头。然后,可以扩展或替换这种格式,以包括任何抽样数据、变量、捕获,从而产生非常详细的信息。例如,可以记录累积请求的数量或客户机访问的不同URL的数量。
日志级别可以使用标准ACL对每个请求进行调整,因此可以自动沉默一些被认为是污染的日志,并在少数流量发生异常行为时(例如,源地址出现过多的URL或HTTP错误)提出警告。管理日志也会以它们自己的级别发出,以通知服务器的丢失或恢复情况。
每个前端和后端可以使用多个独立的日志输出,从而简化了多租户。日志最好是通过UDP发送,可能是JSON编码的,并且在可配置的行长之后被截断,以保证传递。但是,也可以将它们发送到stdout/stderr或任何文件描述符,以及客户端可以订阅以检索它们的环形缓冲区。
HAProxy提供了一个具有身份验证、安全级别和范围的基于web的统计报告接口。因此,可以为每个托管客户提供他自己的页面,只显示他自己的实例。此页面可以位于常规网站的隐藏URL部分,因此无需打开新端口。此页面还可以报告其他HAProxy节点的可用性,这样,如果一切都如预期的那样一目了然,就很容易发现。视图具有许多可访问的详细信息(例如错误原因、最后访问和最后更改持续时间等),这些信息也可以作为CSV表访问,其他工具可以导入这些表来绘制图形。该页可自刷新,用作大型显示器上的监视页。在管理模式下,页面还允许更改服务器状态以简化维护操作。
还提供了Prometheus导出程序,以便根据部署情况以不同的格式使用统计数据。
HAProxy的设计是为了在正常的生产环境中保持非常稳定和安全的管理。它作为一个可执行文件提供,不需要任何安装过程。多个版本可以很容易地共存,这意味着可以(并建议)按照重要的顺序逐步升级实例,而不是一次性迁移所有实例。配置文件易于版本化。配置检查是脱机进行的,因此不需要重新启动可能会失败的服务。在配置检查期间,可能会检测到一些高级错误(例如,隐藏另一个错误的规则,或无法工作的粘性),并提出详细的警告和配置提示来修复这些错误。向后配置文件兼容性的时间非常遥远,版本1.5仍然完全支持13年前编写的1.1版本的配置,1.6只放弃了对几乎未使用的、过时的关键字的支持,这些关键字可以进行不同的操作。配置和软件升级机制是平滑和无干扰的,因为它允许新旧进程共存在系统上,每个进程都处理自己的连接。启动时报告系统状态、生成选项和库兼容性。
一些高级特性允许应用程序管理员平稳地停止服务器,检测服务器上没有任何活动,然后将其断开、停止、升级并确保在升级时不占用任何通信量,然后在不向公众开放的情况下通过正常路径再次测试它,所有这些都不涉及HAProxy。这可以确保即使是复杂的生产操作也可以在开放时间内使用所有可用的技术资源来完成。
该进程试图尽可能节省资源,使用内存池来节省分配时间和限制内存碎片,在发送有效负载缓冲区时立即释放其内容,并支持强制执行强内存限制,在此限制之上,连接必须等待缓冲区可用,而不是分配更多内存。此系统有助于确保在某些严格的环境中使用内存。
命令行接口(CLI)可作为UNIX或TCP套接字使用,用于执行许多操作和检索故障排除信息。在这个套接字上所做的一切都不需要进行配置更改,因此它主要用于临时更改。使用此接口,可以更改服务器的地址、重量和状态,查询统计数据和清除计数器,转储和清除粘性表,可能会有选择地根据关键条件,转储和关闭客户端和服务器端连接,转储捕获的错误,详细分析错误的原因和位置,转储、添加和删除ACL和地图中的条目,更新TLS共享机密,对任意前端(在共享主机环境中有用)应用连接限制和速率限制,以及禁用特定的前端倾向于释放侦听端口(当白天操作被禁止并且仍然需要修复时很有用)。允许动态更新证书及其配置,并启用和查询通信量的每个处理步骤的跟踪。
对于必须使用SNMP的环境,至少有两个代理存在,其中一个提供了HAProxy源,并依赖于NetSNMPPerl模块。另一个包提供了商业包,不需要Perl。两者的覆盖面大致相等。
通常建议在部署HAProxy的机器上安装4个实用程序:
socat
(为了连接到CLI,尽管Netcat的某些分支在某种程度上也可以这样做);halog
来自最新的HAProxy版本:这是日志分析工具,它解析本地TCP和HTTP日志非常快(每秒1至2 GB),并提取有用的信息和统计信息,例如每个URL的请求、每个源地址、按响应时间或错误率排序的URL、终止代码等;tcpdump
:强烈建议采取必要的网络跟踪来解决日志中显示的问题。有一段时间,应用程序和haxy的分析将出现分歧,网络跟踪是判断谁对谁错的唯一途径。由于tcpdump的存在,在网络堆栈和管理程序中检测bug也是相当常见的;strace
:是TCPdump的同伴。它将报告HAProxy真正看到了什么,并将帮助解决操作系统负责的问题和HAProxy负责的问题。当怀疑HAProxy中的bug时,通常会请求Strace。根据部署的操作系统HAProxy,某些额外的功能可能是可用的或需要的。虽然在许多平台上都支持HAProxy,但是HAProxy主要是在Linux上开发的,这就解释了为什么某些特性只能在这个平台上使用。
透明的绑定和连接功能、对绑定到特定网络接口的连接的支持以及将多个进程绑定到相同的IP地址和端口的能力只能在linux和bsd系统上使用,尽管只有linux才能对可用进程之间的传入请求执行内核端的负载平衡。
在Linux上,还有许多额外的特性和优化,包括支持网络名称空间(也称为“容器”),允许HAProxy成为所有容器之间的网关,能够在客户端连接上设置MSS、Netfilter标记和IP TOS字段,在侦听端支持TCP FastOpen,当内核检测到客户端已在配置超时之前消失时,TCP用户超时可以让内核快速关闭连接,TCP剪接可以让内核在连接的两侧转发数据,从而避免多个内存副本,启用“延迟接受”绑定选项的能力仅在内核缓冲区中数据可用时才得到传入连接的通知,以及使用ACK确认连接的能力(有时称为“回拨”),这是通过“tcp智能连接”选项启用的。因此,如果在系统上检测到此行为,则必须修复该行为,而不管HAProxy保护自己不受其害。
在Linux上,一个新的启动进程可以与前一个进程通信,以重用它的侦听文件描述符,以便在进程替换过程中不会中断侦听套接字。
HAProxy可以通过支持Lua嵌入式语言来构建,它为复杂的请求或响应操作、路由决策、统计处理等开辟了广阔的新可能性。使用Lua,甚至可以建立到其他服务器的并行连接来交换信息。例如,通过这种方式可以(尽管很复杂)开发一个身份验证系统。有关如何使用Lua的更多信息,请参阅文件“doc/lua-api/index.rst”中的文档。
在任何时候,管理员都可以通过CLI进行连接,并在各种内部子系统中启用跟踪。默认情况下会提供不同级别的详细信息,以便在实践中每请求从一行到每请求500行之间的任何内容都可以被检索。过滤器以及自动捕获/关闭/暂停机制是可用的,这样就可以真正地等待某个事件并详细观察它。这非常方便地诊断来自错误服务器和客户端的协议违反或拒绝服务攻击。
典型的CPU使用情况显示,HAProxy的处理时间为15%,而TCP或HTTP关闭模式下的内核处理时间为85%,而在HTTP保持生存模式下,HAProxy的处理时间约为30%,内核的处理时间为70%。这意味着操作系统及其调优对全局性能有很大影响。
用户之间的使用差异很大,一些关注带宽,另一些关注请求速率,另一些则关注连接并发性,另一些则关注SSL性能。本节旨在提供一些元素来帮助完成这项任务。
重要的是要记住,每项操作都要付出一定的代价,因此每个单独的操作都在其他操作的基础上增加了它的开销,在某些情况下可以忽略不计,在其他情况下可能占主导地位。
在处理来自连接的请求时,我们可以说:
因此,在实际应用中,处理有效负载字节比处理头字节要便宜,因此,对于大对象(每个卷单元的请求很少),实现高网络带宽要比对小对象(每个卷单元有多个请求)更容易。这就解释了为什么最大带宽总是用大对象来测量,而请求速率或连接速率则是用小对象来测量的。
有些操作在多个进程上扩展得很好,分布在多个CPU上,而另一些操作则没有扩展。网络带宽不太大,因为CPU很少是大对象的瓶颈,主要是网络带宽和到达网络接口的数据总线。在处理本地端口表时,由于系统中有几个锁,连接速率不能很好地扩展到多个处理器上。持久连接上的请求速率扩展得很好,因为它不需要太多内存或网络带宽,也不需要访问锁定的结构。TLS键计算规模非常好,因为它完全是CPU限制.TLS恢复得比较好,但在大约4个进程中达到了限制,其中访问共享表的开销抵消了预期从更多的能量中获得的小收益。
人们可以期望一个非常好的系统的性能数字在以下范围内。重要的是将它们视为数量级,并根据处理器、IRQ设置、内存类型、网络接口类型、操作系统调优等预期在任何方向上都会发生重大变化。
在运行在3.7GHz的Core i7上,可以找到以下数字,它配备了一个双端口10 Gbps的NIC,运行Linux内核3.10、HAProxy 1.6和OpenSSL 1.0.2。HAProxy在一个专用CPU核心上作为一个进程运行,另外两个内核专门用于网络中断:
因此,一个很好的经验法则是,请求率除以TLS保持活动和TLS恢复之间的10,在TLS恢复和TLS重新协商之间除以10,而在HTTP保持活动和HTTP关闭之间仅除以3。另一个好的经验法则是记住,一个带有AES指令的高频核可以完成每个核心大约5 Gbps的AES-GCM。
拥有更多的核心很少有帮助(除了TLS),甚至由于频率较低而适得其反。一般来说,少数高频核更好。
另一个好的经验法则是,在同一台服务器上,HAProxy将能够饱和:
HAProxy是GPLv 2许可证所涵盖的一个开源项目,这意味着每个人都可以重新分发它,前提是在请求时也提供对源代码的访问,特别是在进行任何修改的情况下。
HAProxy作为一个名为“master”或“mainline”的主要开发分支,一旦代码被认为是稳定的,就会从它派生出新的分支。许多网站自愿地在生产中运行一些开发分支,要么是为了参与项目,要么是因为它们需要一个前沿特性,它们的反馈对于修复bug和判断正在开发的版本的整体质量和稳定性具有很高的价值。
在代码足够稳定时创建的新分支构成了稳定的版本,并且通常维护几年,因此即使不是最新版本,也不会出现迁移到较新分支的紧急情况。一旦一个稳定的分支被发布,它可能只会收到bug修复,当这使得用户的生活变得更容易的时候,很少会得到小的特性更新。进入稳定分支的所有修复都必须来自主分支。这保证了升级后不会丢失任何修复。因此,如果您修复了一个bug,请针对主分支而不是稳定的分支进行修补程序。你甚至会发现它已经修好了。此过程还确保稳定分支中的回归非常罕见,因此没有任何借口不升级到当前分支中的最新版本。
分支的编号是用用点分隔的两位数,例如“1.6”。自1.9以来,拥有奇数二位数的分支机构大多专注于敏感的技术更新,并且更多地针对高级用户,因为它们可能会引发比其他用户更多的bug。它们只维持一年左右,不得在紧急情况下无法收回的地方部署。一个完整的版本包括一个或两个子版本号,表示修复级别。例如,版本1.5.14是在1.5.0版本发布之后,在分支1.5中发布的第14个修复版本。它包含126个针对单个bug的修复、24个文档更新和75个其他支持补丁,其中大多数是修复上述126个bug所必需的。在一个稳定的分支中,一个现有的特性永远不会被修改或删除,以保证在同一个分支中的升级永远是无害的。
HAProxy有多种来源,有不同的释放节奏:
为了确保您使用的版本是分支中的最新版本,您需要这样做:
验证您正在运行的HAProxy可执行文件:默认情况下,有些系统会将其交付给系统,并且管理员会将它们的版本安装在系统上的其他地方,因此在启动脚本中验证使用哪个版本是很重要的;
确定您的HAProxy版本来自哪个源。为此,输入“haxy-v”通常就足够了。
开发版本将出现如下所示,在分支编号后面加上“dev”字:
HA-Proxy version 1.6-dev3-385ecc-68 2015/08/18
稳定的版本将出现如下,以及操作系统供应商提供的未经修改的稳定版本:
HA-Proxy version 1.5.14 2015/07/02
并且稳定版本的夜间快照将出现在版本之后的十六进制序列中,并且显示快照的日期而不是发布日期:
HA-Proxy version 1.5.14-e4766ba 2015/07/29
任何其他格式都可以指示具有自己的修补程序集的特定于系统的包。例如,HAProxy企业版本将以以下格式出现(分支-最新提交- revision):
HA-Proxy version 1.5.0-994126-357 2015/07/02
此外,Version2.1及更高版本将包括一个“Status”行,指示该版本对生产是否安全,如果安全,直到何时,以及一个指向影响该版本的已知bug列表的链接。
对于特定于系统的包,您必须检查供应商的包存储库或更新系统,以确保您的系统仍然受到支持,并且仍然为您的分支提供修复。对于来自haproxy.org的社区版本,只需访问该站点,验证您的分支的状态,并将最新版本与您的版本进行比较,以确定您是否在最新版本上。否则你可以升级。如果您的分支不再维护,那么您肯定很晚了,必须考虑升级到更新的分支(在这样做时仔细阅读自述文件)。
HAProxy必须根据其来源进行更新。通常,它遵循系统供应商升级包的方式。如果它是从源代码获取的,请在提取源代码后阅读源代码目录中的自述文件,并按照操作系统的说明进行操作。
HAProxy与下面列出的某些产品集成得相当好,这就是为什么这里提到它们,即使它们与HAProxy没有直接关系。
Apache是标准HTTP服务器。这是一个非常完整和模块化的项目,既支持文件服务,也支持动态内容。它可以作为一些应用服务器的前端。它甚至可以代理请求和缓存响应。在所有这些用例中,通常需要一个前端负载均衡器。Apache可以在各种模式下工作,有些模式比其他模式更重。某些模块仍然需要更重的预分叉模型,并将防止Apache与大量连接很好地扩展。在这种情况下,HAProxy可以通过将每个服务器的连接限制强制为一个安全值来提供巨大的帮助,并将大大加快服务器的速度,并保存其资源,以便应用程序更好地使用这些资源。
Apache可以使用“mod_rpaf”扩展从X-Forwarded-For header中提取客户端的地址。当在配置中指定“OptionFordfor”时,HAProxy将自动提供此标头。当它暴露在互联网上时,HAProxy也可以为Apache提供一个很好的保护,在那里它能更好地抵御多种类型的DoS攻击。
Nginx是第二个标准HTTP服务器。就像Apache一样,它涵盖了广泛的特性。Nginx是建立在与HAProxy类似的模型之上的,因此它在处理数万个并发连接时没有问题。当用作一些应用程序的网关(例如使用包含的PHPFPM)时,设置一些前端连接限制以减少PHP应用程序的负载通常是有益的。HAProxy显然是有用的,无论是作为一个常规的负载平衡器和交通调节器,以加快PHP通过消除它。另外,由于这两种产品由于其事件驱动的体系结构而占用很少的CPU,所以通常很容易将它们安装在同一个系统上。Nginx实现了HAProxy的代理协议,因此HAProxy很容易将客户端的连接信息传递给Nginx,以便应用程序获取所有相关信息。一些基准测试还表明,对于大型静态文件服务,通过优化OS的缓存命中率(基本上乘以服务器节点数),在Nginx前面的HAProxy上实现一致的散列是有益的。
Varnish是一个智能缓存反向代理,可能最好描述为一个web应用程序加速器。Varnish不实现SSL/TLS,并希望将其所有CPU周期用于其最佳性能。Varnish还实现了HAProxy的代理协议,这样HAProxy可以作为SSL卸载器和负载均衡器很容易地部署在Varish前面,并将所有相关的客户端信息传递给它。另外,如果服务器提供了压缩对象,但不进行压缩,Varish自然支持缓存中的解压缩。然后,当后端服务器没有实现压缩时,可以使用HAProxy来压缩传出数据,尽管在负载均衡器上压缩很少是一个好主意,除非流量很低。
当建立跨多个节点的大型缓存场时,HAProxy可以利用一致的URL散列将负载智能地分配到缓存节点,并避免缓存重复,从而导致缓存的总大小,即所有缓存节点的总和。此外,在HAProxy上对非常小的哑对象进行短暂的缓存有时可以节省网络往返,并减少HAProxy和Varish节点上的CPU负载。这是唯一可能的,因为对这些对象在Varish上不进行处理(这通常被称为“偏袒图标缓存”的概念,通过这个概念,有时可以避免大量无用的下游请求)。但是,不要在任何其他缓存前面长时间(超过几秒钟)启用HAProxy缓存,这将使故障排除变得非常复杂,而不会带来真正的节省。
LinuxVirtualServer(LVS或IPV)是Linux内核中包含的第4层负载均衡器。它在数据包级别工作,并处理TCP和UDP。在大多数情况下,它更多地是一个补充,而不是一个替代,因为它根本没有第7层的知识。
Pound 是另一个著名的负载平衡器。它比HAProxy简单得多,功能也少得多,但是对于许多非常基本的设置,两者都可以使用。它的作者总是把重点放在代码的可审核性上,并且希望保持低的特性集。它基于线程的体系结构扩展得不太好,连接计数很高,但它是一个很好的产品。
Pen是一个相当轻的负载平衡器。它支持ssl,使用固定大小的客户端IP地址表来维护持久性。它支持面向数据包的模式,允许它在一定程度上支持直接服务器返回和UDP。它用于小负载(持久化表只有2048个条目)。
Nginx可以在一定程度上实现一些负载平衡,尽管它显然不是它的主要功能。生产流量被用来检测服务器故障,负载平衡算法更加有限,粘性也非常有限。但在一些已经存在的简单部署场景中,它是有意义的。好的是,由于它与HAProxy集成得很好,所以以后添加HAProxy没有什么问题,因为它的极限已经达到了。
Varnish 也对后端服务器进行一些负载平衡,并支持真正的健康检查。但是,它并不能实现粘性,所以就像Nginx一样,只要不需要粘性,这就足够了。类似地,由于HAProxy和Varish集成得非常好,以后很容易将其添加到混合中以补充特性集。