负载均衡 - HAProxy


现在常用的三大开源软件负载均衡器分别是Nginx、LVS、HAProxy。三大软件特点如下:

LVS

(1)抗负载能力强,抗负载能力强、性能高、能达到F5硬件的60%;对内存和cpu资源消耗比较低。
(2)工作在网络4层,通过VRRP协议转发(仅作分发之用),具体的流量由linux内核处理,因此没有流量产生。
(3)稳定性、可靠性好,自身有完美的热备方案(如:LVS+Keepalived)。
(4)应用范围比较广,可以对所有应用做负载均衡。
(5)不支持正则处理,不能做动静分离。
(6)支持负载均衡算法:rr(轮循)、wrr(加权轮循)、lc(最小连接)、wlc(权重最小连接)。
(7)配置复杂,对网络依赖比较大,稳定性很高。

Ngxin

(1)工作在网络的七层之上,可以针对http应用做一些分流的策略,比如针对域名、目录结构。
(2)Nginx对网络的依赖比较小,理论上能ping通就能进行负载均衡。
(3)Nginx安装和配置比较简单,测试起来比较方便。
(4)也可以承担高的负载压力且稳定,一般能支撑超过1万次的并发。
(5)对后端服务器的健康检查,只支持通过端口检测,不支持通过url来检测。
(6)Nginx对请求的异步处理可以帮助节点服务器减轻负载。
(7)Nginx仅能支持http、https和Email协议,这样就在使用范围较小。
(8)不支持Session的直接保持,但能通过ip_hash来解决,对Big request header的支持不是很好。
(9)支持负载均衡算法:Round-robin(轮循)、Weight-round-robin(加权轮循)、IP-hash(IP哈希)。
(10)Nginx还能做Web服务器即Cache功能。

HAProxy

(1)支持两种代理模式:TCP(四层)和HTTP(七层)。
(2)能够补充Nginx的一些缺点比如Session的保持,Cookie的引导等工作。
(3)支持url检测后端的健康状态。
(4)更多负载均衡策略比如:动态加权轮循(Dynamic Round Robin),加权源地址哈希(Weighted Source Hash),加权URL哈希和加权参数哈希(Weighted Parameter Hash)。
(5)单纯从效率上来将HAProxy更会比Nginx有更出色的负载均衡速度。
(6)HAProxy可以对Mysql进行负载均衡,对后端的DB节点进行检测和负载均衡。
(7)支持负载均衡算法:Round-robin(轮循)、Weight-round-robin(加权轮循)、source(源地址保持)、RI(请求URL)、rdp-cookie(根据cookie)
(8)不能做Web服务器即Cache 

三大负载均衡使用场景

(1)网站建设初期,可以选用Nginx/HAProxy作为反向代理负载均衡(或者流量不大都可以不选用负载均衡),因为其配置简单,性能也能满足一般的业务场景。如果考虑到负载均衡器是有单点问题,可以采用Nginx+Keepalived/HAProxy+Keepalived避免负载均衡器自身的单点问题。

(2)网站并发达到一定程度之后,为了提高稳定性和转发效率,可以使用LVS、毕竟LVS比Nginx/HAProxy要更稳定,转发效率也更高。不过维护LVS对维护人员的要求也会更高,投入成本也更大。

需要注意的是

Nginx和HAProxy比较:Nginx支持七层、用户量最大,稳定性比较可靠。HAProxy支持四层和七层,支持更多的负载均衡算法,支持session保存等。具体选择看使用场景。目前来说HAProxy由于弥补了一些Nginx的缺点致使其用户量也不断在提升。

衡量负载均衡器好坏的几个重要因素

(1)会话率:单位时间内的处理的请求数

(2)会话并发能力:并发处理能力

(3)数据率:处理数据能力

经过官方测试统计,haproxy 单位时间处理的最大请求数为20000个,
可以同时维护40000-50000个并发连接,最大数据处理能力为10Gbps。
综合上述,haproxy是性能优越的负载均衡、反向代理服务器。


HAProxy简介

HAProxy是法国人Willy Tarreau开发的一款可应对客户端10000以上的同时连接的高性能的TCP和HTTP负载均衡器。由于其丰富强大的功能在国内备受推崇,是目前主流的负载均衡器。Haproxy是一个开源的高性能的反向代理或者说是负载均衡服务软件之一,它支持双机热备、虚拟主机、基于TCP和HTTP应用代理等功能。其配置简单,而且拥有很好的对服务器节点的健康检查功能(相当于keepalived健康检查),当其代理的后端服务器出现故障时,Haproxy会自动的将该故障服务器摘除,当服务器的故障恢复后haproxy还会自动重新添加回服务器主机。

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

Haproxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。haproxy运行在当前的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整合进当前架构中,同时可以保护web服务器不被暴露到网络上。

Haproxy软件引入了frontend,backend的功能,frontend(acl规则匹配)可以根据任意HTTP请求头做规则匹配,然后把请求定向到相关的backend(server pools等待前端把请求转过来的服务器组)。通过frontend和backend,可以很容易的实现Haproxy的7层负载均衡代理功能。

HAProxy是一种高效、可靠、免费的高可用及负载均衡解决方案,非常适合于高负载站点的七层数据请求。客户端通过HAProxy代理服务器获得站点页面,而代理服务器收到客户请求后根据负载均衡的规则将请求数据转发给后端真实服务器。

同一客户端访问服务器,HAProxy保持会话的三种方案:

(1)HAProxy将客户端IP进行Hash计算并保存,由此确保相同IP来访问时被转发到同一台真实服务器上。
(2)HAProxy依靠真实服务器发送给客户端的cookie信息进行会话保持。
(3)HAProxy保存真实服务器的session及服务器标识,实现会话保持功能。

HAProxy的工作原理

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

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

HAProxy的优点

(1)免费开源,稳定性也是非常好。单HAProxy也跑的不错,稳定性可以与硬件级的F5相媲美。

(2)根据官方文档,HAProxy可以跑满10Gbps,这个数值作为软件级负载均衡器也是相当惊人的。

(3)HAProxy支持连接拒绝:因为维护一个连接的打开的开销是很低的,有时我们需要限制攻击蠕虫(attack bots),也就是说限制它们的连接打开从而限制它们的危害。这个已经为一个陷于小型DDoS攻击的网站开发了而且已经拯救了很多站点,这个优点也是其它负载均衡器没有的。

(4)HAProxy支持全透明代理(已具备硬件防火墙的典型特点):可以用客户端IP地址或者任何其它地址来连接后端服务器。这个特性仅在Linux 2.4/2.6内核打了tcp proxy补丁后才可以使用。这个特性也使得为某特殊服务器处理部分流量同时又不修改服务器的地址成为可能。

(5)HAProxy现在多用于线上的MySQL集群环境,常用它作为MySQL(读)负载均衡。

(6)自带强大的监控服务器状态的页面,实际环境中可以结合Nagios进行邮件或短报警。

HAproxy主要工作位置

image-20240919212218446

  • - HAProxy支持http反向代理

  • - HAProxy支持动态程序的反向代理

  • -HAProxy支持基于数据库的反向代理

HAProxy 相关术语

访问控制列表(ACL)

在负载均衡中,ACL用于测试某些状况,并根据测试结果执行某些操作(例如选定一套服务器或者屏蔽某条请求),如下ACL示例

acl url_blog path_beg /blog

如果用户请求的路径以/blog 开头,则匹配这条ACL。举例来说,http://127.0.0.1/blog/blog-entry-1请求即符合这一条件。

Backend

所谓的backend是指一组服务器,负责接收各转发请求。Backend在HAProxy配置中的backend部分进行定义。一般来讲,backend的定义主要包括:

- 使用哪种负载均衡算法

- 一套服务器与端口列表

一条backend能够容纳一套或者多套服务器一一总体而言向backend中添加更多服务器将能够将负载扩散至更多的服务器,从而增加潜在负载容量。这种方式也能够提升可靠性,从而应对服务器发生故障的情况。

下面来看一套双backend配置示例,分别为web-backend与blog-backend,其各自包含两套web服务器,且监听端口80:

backend web-backend
  balance roundrobin
  server web1 web1.kevin.com:80 check
  server web2 web2.kevin.com:80 check
 
backend blog-backend
  balance roundrobin
  mode http
  server blog1 blog1.kevin.com:80 check
  server blog2 blog2.kevin.com:80 check

其中:

  • balance roundrobin行指定负载均衡算法,具体细节参考负载均衡算法部分
  • mode http 则指定所使用的7层代理机制,具体参考负载均衡类型部分
  • 结尾处的check 选项指定在这些后端服务器上执行运行状态检查

Frontend

一条frontend负责定义请求如何被转发至backend。Frontend在HAProxy配置中的frontend部分。其定义由以下几个部分组成:

  • 一组IP地址与一个端口(例如10.1.1.2:80,*:443,等等)
  • ACL
  • use_backend规则,其负责根据当前ACL条件定义使用哪个backend,而default_backend规则处理一切其它情况

可以将同一frontend配置至多种不同网络流量类型!

负载均衡的基本类型

无负载均衡

简单的无负载均衡Web应用环境,用户会直接接入Web服务器,即ktest.com且其中不存在负载均衡机智。如果单一Web服务器发生故障,用户将无法进入到该服务器。另外,如果多位用户同时访问该服务器,且其无法处理该负载,则可能出现相应缓慢或者无法接入的情况

四层负载均衡

最为简单的负载均衡方式,将网络流量引导至多台服务器以使用四层(即传输层)负载均衡。这种方式会根据IP范围与端口进行用户流量转发(如果有请求执行http://ktest.com/anything,则该流量将被转发至backend,并由其处理全部指向ktest.com在端口80上的请求)

frontend web_80                            
   mode tcp
   bind :80
   default_backend web-backend
 
backend web-backend
   mode tcp
   server 192.168.1.25 192.168.1.25:80 weight 1 check inter 1s rise 2 fall 2
   server 192.168.1.26 192.168.1.26:80 weight 1 check inter 1s rise 2 fall 2
  • 用户访问负载均衡器,后者将用户请求转发至后端服务器的web-backend组。被选定的后端服务器将直接影响用户请求。总体而言,web-backend中的全部服务器都应当拥有同样的内容,否则用户可能会遭遇内容不一致的问题。请注意后端两个Web服务器都接入同样的数据库服务器。

七层负载均衡

另一种更为复杂的负载均衡方式,网络流量使用7层(即应用层)负载均衡。使用7层意味着负载均衡器能够根据用户的请求内容将请求转发至不同后端服务器。这种方式允许大家在同一域名及端口上运行多套Web应用服务器。下图为一套简单的7层负载均衡示例,在本示例中,如果用户向ktest.com/blog发送请求,则会被转发至blog后端,其包含一组运行有同一blog应用的服务器。其它请求则会被转发至web-backend,其负责运行其应用。本示例中的两套backend皆使用同样的数据库服务器。

frontend http
   bind *:80
   mode http
 
  acl url_blog path_beg /blog
  use_backend blog-backend if url_blog
 
  default_backend web-backend
 
backend web-backend
    mode http
    balance roundrobin
    cookie SERVERID insert indirect nocache
    option httpclose
    option forwardfor
    server web01 192.168.1.25:80 weight 1 cookie 3 check inter 2000 rise 2 fall 5
    server web01 192.168.1.26:80 weight 1 cookie 3 check inter 2000 rise 2 fall 5

这部分片段配置一套名为http的frontend,其负责处理端口80上的所有输入流量。

  • acl url_blog path_beg 这里的/blog表示匹配那些用户请求路径以/blog开头的请求。
  • use_backend blog-backend if url_blog 这里采用该ACL将流量代理至blog-backend。
  • default_backend web-backend 这里指定全部其它流量将被转至web-backend。

负载均衡的调度算法

HAProxy支持的负载均衡算法

负载均衡算法用于检测后端中的哪套服务器被负载均衡机制选定进行请求响应。HAProxy提供多种算法选项。除了负载均衡算法之外,我们还能够为服务器分配一个weight参数来指定该服务器被选定的频率。由于HAProxy提供多种负载均衡算法,下面说明几种常用的算法:

  • roundrobin:表示简单的轮循,即客户端每访问一次,请求轮循跳转到后端不同的节点机器上
  • static-rr:基于权重轮循,根据权重轮循调度到后端不同节点
  • leastconn:加权最少连接,表示最少连接者优先处理
  • source:表示根据请求源IP,这个跟Nginx的IP_hash机制类似,使用其作为解决session问题的一种方法
  • uri:表示根据请求的URL,调度到后端不同的服务器
  • url_param:表示根据请求的URL参数来进行调度
  • hdr(name):表示根据HTTP请求头来锁定每一次HTTP请求
  • rdp-cookie(name):表示根据cookie(name)来锁定并哈希每一次TCP请求
常用的负载均衡算法
  1. 轮循算法:roundrobin,Round Robin会对服务器进行轮流选定,亦为HAProxy的默认算法。即客户端每访问一次,请求就跳转到后端不同的节点机器上。
  2. 根据请求源IP算法:source,其根据源IP(即用户IP地址)进行服务器选定。通过这种方式,我们可以确定同一用户接入同一服务器。
  3. 最少连接者先处理算法:lestconn,选定连接数量最少的服务器——建议在周期较长的会话中使用这一算法。同一后端中的服务器亦会以轮循方式进行轮流选定。
粘性会话

部分应用要求用户始终接入同一后端服务器,这一点需要利用粘性会话实现,其要求在backend中使用appsession参数。

运行状态检查

HAProxy利用运行状态来检测后端服务器是否可用于处理请求。通过这种方式,我们不必以手动方式撤下不可用的后端服务器。默认运行状态检查会与目标服务器建立一条TCP连接,即检查后端服务器是否在监听所配置的IP地址和端口。

如果某套服务器未能通过运行状态检查,并因此无法相应请求,则其会在后端中被自动禁用——意味着流量将不再被转发至该服务器处,直到其重新恢复状态。如果后端中的全部服务器皆发生故障,则服务将不再可用,直到至少一套后端服务器重新恢复正常。

对于特定后端类型,列如特定状态下的数据库服务器,默认运行状态检查可能无法正确识别其正常与否。

其它解决方案

如果觉得HAProxy可能太过复杂,那么以下解决方案同样值得考虑:

  • LVS - 一套简单且快速的4层负载均衡器,多数linux发行版都内置有这套方案
  • Nginx - 一套快速且可靠的Web服务器,亦可用于代理及负载均衡。Nginx通常与HAProxy相结合以实现缓存及压缩功能。