HAProxy

可靠、高性能的 TCP/HTTP 负载均衡器


快速链接

新闻快报
最近新闻
描述
设计选择
支持平台
性能
可靠性
安全
下载
文档
Live demo
商业支持
使用HAProxy的产品
贡献者
其他解决方案
联系方式
邮件列表归档
10-Gbps 负载均衡


Willy TARREAU
你想捐赠?


新闻快报

2009年9月26日

September 24th, 2009 : 1.4-dev3

    Most of the internal changes planned for version 1.4 have been completed, so it was time to release a new clean snapshot. The architecture is now ready to permit keep-alive, SSL or FastCGI developments. Some more changes are planned but the remaining ones should be a lot easier to perform without breaking everything.

    Compared to latest stable 1.3.20 version, 1.4-dev3 provides new features, among which support for the CLF log format, RDP protocol load-balancing and persistence, a new interactive CLI, an improved HTML stats page, support for inspecting HTTP contents in TCP frontends and switching to HTTP backends (allowing HTTP+SSL to coexist on the same port), support for forcing of the TCP MSS on frontends, smart network optimizations to reduce the number of TCP packets in a session, runtime-configurable buffer sizes, support for more than 64k concurrent connections, config parser support for "no option xxx" to disable options that were enabled by default, and correct 1xx status code processing. Developments to support keep-alive have already started, and if time permits, SSL integration will be attempted. The code looks amazingly stable for the amount of changes, and will probably not change much anymore, so any bug found in this version must be reported and fixed. Also, new feature submissions should be based on this version. It will be easier to implement for submitters and for me to merge.

    Several large sites are already running on 1.4-dev2 with great success. This one should be even better, but given the number of changes, it should be monitored more closely at the beginning.

    Last, I have a very good news that I hope will give ideas to others : Exceliance and Loadbalancer.org have both agreed to contribute some manpower and money to implement the complete persistence framework that everyone is dreaming about into haproxy. That's a tough work and I'm not certain it will be ready for 1.4 (though it might, depending if I'm as late on my releases as usual). I would personally like to thank them both for their contributions. When you have to put your money in commercial solutions, please never forget to consult first the guys who involve time and money in opensource projects, because they are the ones who help the projects evolve and live !

最近新闻...

最新版本

分支说明最后版本Released注意
1.3.x开发 GIT 未发布也许不稳定
1.3.161.3.16-rc 1.3.16-rc1 2009/03/09 Release Candidate (Beta)
1.3.151.3.15-maint 1.3.15.7 2008/12/04 推荐版本
1.3.141.3.14-maint 1.3.14.11 2008/12/04 之前版本
1.2.x1.2-stable 1.2.18 2008/05/25 仅修复重要bug
1.1.x1.1-stable 1.1.34 2006/01/29 仅修复致命bug
1.0.x1.0-old1.0.22001/12/30无维护

描述

HAProxy提供高可用性负载均衡 以及基于TCP和HTTP应用的代理,它是免费、快速并且可靠的一种解决方案。HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。 HAProxy运行在当前的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整合进您当前的架构中, 同时可以保护你的web服务器不被暴露到网络上, 如下所示:

当前,您有两种主要的版本可以使用:

  • 版本 1.1 - 从2002年开始就服务于很多重要站点
    这是最稳定可靠的版本, 运行时间(uptime)已经长达几年了。该版本目前已经不接受新的特性,仅用于核心关键(mission-critical)的业务.
  • 版本 1.2 - 主要用于大流量的站点
    在1.1的基础上加入了一些新的特性, poll/epoll 的支持用以支持大量的会话(session), 客户端IPv6 应用程序cookie, hot-reconfiguration, 高级的动态流量管理, TCP keepalive, source hash, 加权负载均衡算法, 基于红黑树(rbtree)算法的调度器, 同时还有一个很好的Web状态页面. 尽管1.2还在不断的发展,但是从1.2.8开始已经趋于稳定。

另外, 版本1.3是处于活跃开发阶段的版本, 它支持如下新特性:

  • 内容交换 : 可以根据请求(request)的任何一部分来选择一组服务器, 比如请求的 URI, Host头(header), cookie, 以及其他任何东西. 当然,对那些静态分离的站点来说,对此特性还有更多的需求。
  • 全透明代理 : 可以用 客户端IP地址或者任何其他地址来连接后端服务器. 这个特性仅在Linux 2.4/2.6内核打了cttproxy补丁后才可以使用. 这个特性也使得为某特殊服务器处理部分流量同时又不修改服务器的地址成为可能。
  • 基于树的更快的调度器 : 1.2.16以上的版本要求所有的超时都设成同样的值以支持数以万计的全速连接. 这个特性已经移植到1.2.17.
  • 内核TCP拼接 : 避免了内核到用户然后用户到内核端的数据拷贝, 提高了吞吐量同时又降低了CPU使用率. Haproxy 1.3支持Linux L7SW 以满足在商用硬件上数Gbps的吞吐的需求。
  • 连接拒绝 : 因为维护一个连接的打开的开销是很低的,有时我们很需要限制攻击蠕虫(attack bots), 也就是说限制它们的连接打开从而限制它们的危害。 这个已经为一个陷于小型DDoS攻击的网站开发了而且已经拯救了很多站点。
  • 细微的头部处理 : 使得编写基于header的规则更为简单,同时可以处理URI的某部分。
  • 快而可靠的头部处理 : 使用完全RFC2616兼容的完整性检查对一般的请求全部进行分析和索引仅仅需要不到2ms的时间。
  • 模块化设计 : 允许更多人加入进此项目,调试也非常简单. poller已经分离, 已经使得它们的开发简单了很多. HTTP已经从TCP分离出来了, 这样增加新的七层特性变得非常简单. 其他子系统也会很快实现模块化
  • 投机I/O 处理 : 在一个套接字就绪前就尝试从它读取数据。poller仅推测哪个可能就绪哪个没有,尝试猜测,并且如果成功,一些开销很大的系统调用 就可以省去了。如果失败,就会调用这些系统调用。已知的使用Linux epoll()已经净提升起码10%了。
  • ACLs : 使用任意规则的任意组合作为某动作的执行条件。
  • TCP 协议检查 : 结合ACL来对请求的任意部分进行检查,然后再进行转发。这就可以执行协议验证而不是盲目的进行转发。比如说允许SSL但拒绝SSH。
  • 更多的负载均衡算法 : 现在,动态加权轮循(Dynamic Round Robin),加权源地址哈希(Weighted Source Hash),加权URL哈希和 加权参数哈希(Weighted Parameter Hash)已经实现。其他算法比如Weighted Measured Response Time也很快会实现。

和其他"免费"的负载均衡解决方案不同的是, HAproxy仅被几百或者几千的遍布全球的用户使用, 但是这些用户通常运行很大的站点, 每天有数百万的点击量和几Gbps甚至几万兆(terabytes)吞吐量。 他们需要7x24的可用性并且愿意承受免费软件解决方案的风险, 同时有这些使用技术. 通常, 这种解决方案仅配置为内部使用, 我仅在他们提供给我反馈或者需要新特性的时候才会知道.

设计选择和历史

HAProxy实现了一种事件驱动, 单一进程模型,此模型支持非常大的并发连接数。多进程或多线程模型受内存限制 、系统调度器限制以及无处不在的锁限制,很少能处理数千并发连接。事件驱动模型因为在有更好的资源和时间管理的用户端(User-Space) 实现所有这些任务,所以没有这些问题。此模型的弊端是,在多核系统上,这些程序通常扩展性较差。这就是为什么他们必须进行优化以 使每个CPU时间片(Cycle)做更多的工作。

我从1996当我写Webroute时开始写一个简单的HTTP代理,此代理能建立一个modem访问。 但它的多进程模型的使得它从性能上只能用于home access。两年后,1998年,我写了事件驱动ZProx, 用于压缩TCP流量以加速modem线路。 那时我开始理解事件驱动模型的困难。2000年,在对一个小的应用程序做基准测试时,我大幅的修改了 Zprox以加入HTTP头重写支持。HAProxy的原型由此诞生。第一个版本自身并不实现负载均衡, 但很快被证明那是很需要的。

现在到了2007年, HAproxy的核心引擎已经很可靠而且很健壮,尽管代码里有许多的注释。事件驱动程序是健壮同时又 易崩溃的: 它的代码需要很小心的修改,但结果是它能处理高负载且能够不被攻击打倒。这也是为什么HAProxy仅有限的一些 特性的原因。

需求 SSL 和 Keep-Alive支持的用户。这些特性会使代码变得非常复杂而且会导致多个版本易于崩溃。而且, 这两功能都对会使性能下降:

  • 在负载均衡器本身上实现SSL意味着它自己会成为瓶颈。当负载均衡器的CPU耗尽,响应时间会增大,唯一的 解决办法是在这个负载均衡器前再增加其他负载均衡器。唯一可扩展的解决办法是在客户端和负载均衡器间增设一个SSL/Cache层。 无论如何,这可以使小型站点能够插入SSL,这个目前还在研究中。
  • 在CPU比现在慢100倍的时候,Keep-alive被发明以用来降低CPU的使用率。保持的连接(persistent connections ) 会消耗很多内存 但除非客户端打开了keep-alive,否则没有任何作用。 2006的今天, CPU已经很便宜但是内存却因为架构或价格仍然限制在几GB内。如果某站点需要keep-alive, 这真是一个问题。 高负载的站点通常禁止keep-alive以支持最大的并发客户。不使用keep-alive的真正弊端是会轻微的增大获取网页对象(Object)的时延。 浏览器会对无keep-alive的站点发起双倍的并发请求来弥补这个不足。

不过,我计划在未来的版本中实现这两个功能,因为似乎有些用户的可用性需求高于性能需求,而且对他们来说, 使用这两特性并不会影响他们的性能而且可以减少其他组件数目。

支持的平台

HAProxy目前可以可靠的运行于以下(OS)平台:

运行于Linux 2.6或者打过epoll 补丁的 Linux 内核 2.4上,1.2.5以上版本的haproxy能达到最佳的性能。仅因为一项系统相关的优化:1.1版本默认的poll系统是 select(), 这在大多数操作系统上可用,但是在处理上千个文件描述符时会变得很慢。1.2 默认使用 poll() 替代之前的 select(), 但在某些系统上会比select更慢. 但是, 推荐在Solaris上使用,因为poll在它上面的实现是非常好的. Linux 2.6或打过补丁的Linux 2.4, HAProxy 1.2 默认使用epoll(), epoll在任何压力下都能达到 O(1) 性能, 所以比在其他系统上使用 poll()select() 都更快. FreeBSD因为使用kqueue机制,性能比这个稍强. HAProxy 1.3开始支持这种poller, 但目前并没做基准测试。

基于这些事实,寻找快速负载均衡器的人们可以考虑运行于下列x86或者x86_64硬件的选择:

  1. HAProxy 1.2.13.1+ on Linux 2.4 + epoll
  2. HAProxy 1.2.13.1+ on Linux 2.6.16 + scheduler starvation fixes
  3. HAProxy 1.2.8+ on FreeBSD
  4. HAProxy 1.2.8+ on Solaris 10

注意: 如果你在寻找一个飞速 的web负载均衡解决方案, 我测试过的第二快的平台是HP-DL145 (Dual Opteron-248 at 2.2 GHz)运行于打过 epoll patch的 Linux 内核 2.4 和 haproxy-1.2 上,达到了21000 hits/s 和2 Gbps.对这样一个廉价的系统来说,确实令人很震撼! 最快的是一台 Sun V40Z (Quad Opteron-848 at 2.2 GHz),它在2G的链路上跑到了30000 hits/s . 这比Dual-proc高了50%多, 所以我猜测我们已经到了系统的极限了。另外一方面,系统方面的性能优化也可以大大的提升性能。总之,Dual-Opteron仍然为最佳性价比.

性能

诚然,用户的证据会比长长的示例更具说服力,请查看 Chris Knight's experience with haproxy saturating a gigabit fiber on a video download site. Also, my experiments with Myricom's 10-Gig NICs might be of interest.

HAProxy involves several techniques commonly found in Operating Systems architectures to achieve the absolute maximal performance :

  • 单一进程, 事件驱动模型大大的降低了内容交换的消耗以及内存使用率。每毫秒(ms)处理几百个任务是非常可能的,每个会话(session)仅消耗几KB内存, 而类似Apache这样的模型,每个进程要消耗几MB内存。
  • O(1)事件检查器目前仅运行于Linux上(HAProxy 1.2) ,可以在成千上万的连接中及时检查各种事件。
  • 单缓冲(Single-buffering)尽可能的避免了读和写之间的任何数据拷贝。这大大的节省了CPU以及内存的使用。通常,瓶颈会发生在 CPU和网卡之间的I/O总线上。
  • MRU 内存分配器(memory allocator)使用定长内存池(memory pools)提供及时的内存分配,有利于热门的cache区覆盖访问量低的cache区 (hot cache regions over cold cache ones)。 这显著的减少了创建新session的时间。
  • work factoring, 比如说一次多个accept(),以及在多进程模式下,减少每个interation的accept()数,因此 负载在进程间得到均衡。
  • event aggregation : timing resolution is adapted to match the system scheduler's resolution. This allows many events to be processed at once without having to sleep when we're sure that we would have woken up immediately. This also leaves a large performance margin with virtually no degradation of response time when the CPU usage approaches 100%.
  • two FSMs (finite state machines) per session ensure exact knowledge of client-side and server-side connection state without having to perform a lot of controls at each call to deal with errors. Actions are decided based on the combination of both states and events. For an even improved state-based decision, future versions will use 3 FSMs with a hard-coded transition matrix like what is used in hardware processors and ASICs.
  • reduced footprint for frequently and randomly accessed memory areas such as the file descriptor table which uses 4 bitmaps. This reduces the number of CPU cache misses and memory prefetching time.
  • 优化的HTTP头部(header)分析 : headers are parsed an interpreted on the fly, and the parsing is optimized to avoid an re-reading of any previously read memory area. Checkpointing is used when an end of buffer is reached with an incomplete header, so that the parsing does not start again from the beginning when more data is read.
  • 减少了开销较大的系统调用次数。默认大部分的工作都在用户端(User-Space)完成,比如说时间读取,缓冲集中(buffer aggretion),文件描述符开启和关闭。

All these micro-optimizations result in very low CPU usage even on moderate loads. And even at very high loads, when CPU is saturated, it is quite common to note something like 5% user and 95% system, which means that the HAProxy process consumes about 20 times less than its system counterpart. This explains why the tuning of the Operating System is very important. I personnally build my own patched Linux 2.4 kernels, and finely tune a lot of network sysctls to get the most out of a reasonable machine.

This also explains why Layer 7 processing has little impact on performance : even if user-space work is doubled, the load distribution will look more like 10% user and 90% system, which means an effective loss of only about 5% of processing power. This is why on high-end systems, HAProxy's Layer 7 performance can easily surpass hardware load balancers' in which complex processing which cannot be performed by ASICs has to be performed by slow CPUs. Here is the result of a quick benchmark performed on haproxy 1.3.9 at EXOSEC on a single core Pentium 4 with PCI-Express interfaces:

    简言之,对象大小小于6kB, hit rate能达到10000/s以上。 对象大小大于40kB,也能达到Gbps.

在生产环境中,当非常昂贵的,高端的硬件负载均衡设备突然在7层处理上失效, HAProxy已经多次作为一种紧急解决方案被安装。 硬件负载均衡设备在包级别处理请求,而且很难支持跨多个包的请求和响应太快的请求。因为它们根本没有缓冲(buffering)。另外, 软件负载均衡器使用TCP buffering并且长请求和快响应对它无所谓。A nice side effect of HTTP buffering is that it increases the server's connection acceptance by reducing the session duration, which leaves room for new requests. New benchmarks will be executed soon, and results will be published. Depending on the hardware, expected rates are in the order of a few tens of thousands of new connections/s with tens of thousands of simultaneous connections.

有3个因素用来衡量负载均衡器的性能:

A load balancer's performance related to these factors is generally announced for the best case (eg: empty objects for session rate, large objects for data rate). This is not because of lack of honnesty from the vendors, but because it is not possible to tell exactly how it will behave in every combination. So when those 3 limits are known, the customer should be aware that he will generally be below all of them. A good rule of thumb on software load balancers is to consider an average practical performance of half of maximal session and data rates for average sized objects.

你或许会对10-Gigabit/s页面有兴趣.

可靠性 - keeping high-traffic sites online since 2002

Being obsessed with reliability, I tried to do my best to ensure a total continuity of service by design. It's more difficult to design something reliable from the ground up in the short term, but in the long term it reveals easier to maintain than broken code which tries to hide its own bugs behind respawning processes and tricks like this.

In single-process programs, you have no right to fail : the smallest bug will either crash your program, make it spin like mad or freeze. There has not been any such bug found in the code nor in production for the last 6 years.

HAProxy has been installed on Linux 2.4 systems serving millions of pages every day, and which have only known one reboot in 3 years for a complete OS upgrade. Obsiouvly, they were not directly exposed to the Internet because they did not receive any patch at all. The kernel was a heavily patched 2.4 with Robert Love's jiffies64 patches to support time wrap-around at 497 days (which happened twice). On such systems, the software cannot fail without being immediately noticed !

Right now, it's being used in several Fortune 500 companies around the world to reliably serve millions of pages per day or relay huge amounts of money. Some people even trust it so much that they use it as the default solution to solve simple problems (and I often tell them that they do it the dirty way). Such people still use version 1.1 which sees very limited evolutions and which targets mission-critical usages. It is really suited for such environments because the indicators it returns provide a lot of valuable information about the application's health, behaviour and defects, which are used to make it even more reliable. Version 1.2 has not yet received as much testing as 1.1, but should be considered for high volumes of traffic or to benefit from newest features.

As previously explained, most of the work is executed by the Operating System. For this reason, a large part of the reliability involves the OS itself. Recent versions of Linux 2.4 offer a high level of stability. However, it requires a bunch of patches to achieve a high level of performance. Linux 2.6 includes the features needed to achieve this level of performance, but is not yet stable enough for such usages. The kernel needs at least one upgrade every month to fix a bug or vulnerability. Some people prefer to run it on Solaris (or do not have the choice). Solaris 8 and 9 are known to be really stable right now, offering a level of performance comparable to Linux 2.4. Solaris 10 might show performances closer to Linux 2.6, but with the same code stability problem. I have too few reports from FreeBSD users, but it should be close to Linux 2.4 in terms of performance and reliability. OpenBSD sometimes shows socket allocation failures due to sockets staying in FIN_WAIT2 state when client suddenly disappears. Also, I've noticed that hot reconfiguration does not work under OpenBSD.

当系统达到它的极限时,可靠性会显著下降。这就是为什么正确的调整sysctls 如此重要。没有通用的规则,视系统和应用程序而定。但是要永远避免内存耗尽使用swap。正确的调整应该能够使系统在大的压力下运行几年而不会变慢或者崩溃。

安全性 - 6年未发现一安全漏洞

在部署一个免费的负载均衡器时,安全是一个重要的考虑因素。加固操作系统、限制开放的端口以及可 访问的服务,这些都是可能的,但是负载均衡器本身却暴露在外。因此,我特别小心编程风格。唯一被 发现的漏洞距今已经6年了而且仅仅存活了一周。 它是由于日志被修改而导致。它会出现BUS ERROS 而导致进程崩溃, 但并不意味着可以执行代码: 仅有3字节的溢出,太短而不能放下甚至一个指针 (并且后面还有一个变量)。

不管怎么样,在编写头部处理的代码时总是特别小心。多种不可能的状态会被检查并且返回,会话从创建 到消亡产生的错误都会被处理。一些人已经分析了源代码,并且建议清理这些日志以利于审计。但是我没有接收可能引起可疑操作的补丁。

我建议使用root启动HAProxy因为之后它可以进行chroot并且在启动实例前丢掉它所有的这些权限 如果不是以root启动是无法完成的,因为只有root可以执行chroot().

日志提供了足够的信息来维护一个令人满意的安全级别。它们只能通过UDP发送,因为一旦chroot了, /dev/log UNIX socket是不可读的,并且写如一个文件也是不可能的。下列信息更为有用:

  • 请求者源IP和端口可以在防火墙日志里面看到请求者的来源地。
  • 会话建立时间和防火墙日志是匹配的, 而会话拆除时间通常匹配代理的时间;
  • 正确的请求编码保证请求者不能隐藏任何的不可打印字符也不能欺骗终端 。
  • 特定的请求和回应包头和cookie抓取帮助检测扫描攻击、代理以及受感染的机器。
  • timers help to differentiate hand-typed requests from browsers's.

HAProxy 也提供基于正则表达式的header控制。部分请求、或者请求、回应的header可以被denied, allowed, removed, rewritten, or added。这重用来阻止危险的请求或者编码(encoding)(如: Apache Chunk exploit), 而且可以防止从服务器向客户端意外的泄露信息 。其他功能比如Cache-control检查确定敏感信息不会被上层的proxy意外的缓存住。

下载

源代码遵循GPL v2. Linux/x86和Solaris/Sparc可用的源代码和预编译二进制包可以在这里下载:

文档

目前有3种文档:参考手册: 说明怎么配置HAProxy,架构指南说明各种类型的代理配置,以及 配置手册具有比参考手册更详尽的配置说明。

商业支持 (法国)

如果你觉得你没有时间和能力来配置和维护一个免费的负载均衡器,或者如果你正寻找商业支持以满足你的客户或老板,你可以联系 EXOSEC. 另外一个解决方案是使用Exceliance的 ALOHA 设备 (如下).

使用HAProxy的产品

以下产品或项目使用HAProxy :

  • redWall防火墙
    来源此站: "redWall是一个可启动的CD-ROM防火墙.它的目标是提供一种功能丰富的防火墙解决方案,基于此目标, 它为所有生成的日志文件提供了一个web访问接口!"
  • ExcelianceALOHA设备
    Exceliance是一个法国公司,它销售完全基于haproxy的解决方案,此方案将haproxy集成到一个优化的加固版本的 Formilux,通过功能丰富的Web接口,方便使用,减少了维护量,并且 使用VRRP(box fail-over以及link fail-over)增强了可用性,同时还有配置同步,SSL,透明代理等等。该站点上 有个试用版,可以在VMware上使用。因为那是我工作的公司,所以,很多的功能都在那实现了。:-)
  • Loadbalancer.org
    此公司在英国,目前将haproxy加入到他们的负载均衡解决方案中以提供部分用户需要的基本的7层支持。 他们也是少数肯使用haproxy并捐献给这个项目的商业公司之一。

贡献者

很多热心人贡献了代码给我,这些代码有的被采用了。另外有一些人花了很长的时间分析代码,还有一些人维护着ports以保持更新。

其他解决方案

如果你根本不需要HAProxy的任何功能而想寻找一种更简单的解决方案,你也许可以在此找到你所需要的:

  • Linux Virtual Servers (LVS)
    整合进Linux 2.4和2.6内核的非常快速的3/4层负载均衡. 需要结合Keepalived 使用以实现对服务器的健康检查. 这通常是大多数基于IP的负载均衡器默认的解决方案.
  • Pure 负载均衡器(PLB)
    作者用了和HAProxy一样的事件驱动模型(但它是基于libevent的). 有趣的是, 它有和使用其他模型一样的限制. 然而, 他的目的仅仅是为了实现高性能和可用性, 并没有任何HTTP处理和会话保持.
  • Pound
    Pound可以视为HAProxy的一个补充. 它支持SSL, 可以根据请求的URL进行转发. 它的代码很小,并且为了方便审计, 会一直保持. 它的配置文件也很小. 但是, 它不支持会话保持, 并且它的性能以及多线程模型限制了它仅适用于中型站点.
  • Pen
    Pen是一个很简单的TCP负载均衡器. 它支持高达2048个客户端的基于源IP地址的会话保持。 支持基于IP的ACL. 使用select()并且比Pound支持更大的吞吐量, 但是当并发连接达到几千后很难再扩展.

联系方式

有任何问题或者建议请随时联系我:

经常有人问我是否可以捐赠,所以我(作者Willy TARREAU)专门建立了一个paypal账号。如果你想捐赠.点击这里

FreeNode开了一个关于HAProxy的IRC频道(但在那找不到我,我不去那) :