【负载均衡】深入理解HaProxy

509 阅读5分钟

背景

公司使用的负载均衡框架是HAProxy,我其实还是比较好奇为什么不直接使用nginx的,所以特意来研究并对比一下HAProxy的使用以及原理。

什么是HAProxy

介绍

HAProxy官网:http://www.haproxy.org/

HAProxy文档:http://docs.haproxy.org/

其官网介绍到:

HAProxy 是一种免费、非常快速且可靠的反向代理,提供高可用性负载均衡和 基于 TCP 和 HTTP 的应用程序的代理。它特别适合非常 高流量网站,并为世界上访问量最大的网站提供支持。

通过这段描述,我们可以看出HaProxy的特点:

  • 用途:负载均衡
  • 性能:适合高并发,高流量
  • 代理方式:反向代理
  • 代理的层级:TCP和HTTP层

接下来我们将从这四个特点入手,开始深入研究Haproxy。

负载均衡

负载均衡的概念,这里就不详细介绍了。 我们直接看看HaProxy支持哪些负载均衡算法。

HAProxy负载均衡算法

HAProxy可以通过修改配置文件中的balance字段来修改其调度算法,balance字段可以应用于配置文件的default,frontend,backend的配置块中。

负载均衡算法原理特点
static-rr(静态轮询)按服务器权重进行轮询分配,权重高的服务器获得更多请求,但权重不可动态调整不支持运行时权重修改或慢启动。 后端服务器数量无限制
first(首选优先)按服务器列表顺序分配请求,只有当第一台服务器达到最大连接数(maxconn)时,才分配至下一台忽略权重设置,仅依赖服务器位置和连接数限制。不支持动态权重调整,适用于简单优先级场景。
roundrobin(动态轮询)基于权重的轮询算法,支持运行时通过工具(如socat)动态调整权重,并实现慢启动新加入的服务器逐步增加负载,避免瞬时压力过大。支持最多4095个后端服务器。
leastconn(最少连接)优先将请求分发给当前连接数最少的服务器,结合权重计算(连接数/权重)自动规避过载服务器,提升整体资源利用率。支持动态权重调整和慢启动。
source(源地址哈希)对客户端源IP进行哈希计算,固定将同一IP的请求分发至特定服务器可以保持长会话
uri(URI哈希)基于请求URI的哈希值分配流量,相同URI的请求定向到同一服务器缓存优化场景,如CDN节点或静态资源分发
url_param(URL参数哈希)根据URL中指定参数(如nameage)的值进行哈希分配,支持多参数组合可以按业务参数(如用户ID、地理位置)进行定向请求
hdr(name)(HTTP头哈希)根据HTTP头字段(如User-AgentHost)哈希分配请求,若头字段缺失则退化为轮询可以按设备类型(移动/PC)或域名分流请求

针对每个进行hash运算的算法,都可以指定一个hash-type,来配置hash算法(取模法 或者一致性哈希)

比较Nginx的负载均衡算法

Nginx默认的算法是不支持动态权重调整的,需要使用付费的Nginx Plus。

HAProxy相比Nginx也更加支持会话保持,如支持IP、Cookie、URL,URL_Param,而Nginx只支持Ip_hash

高性能揭秘

官网对于性能的描述如下:

image.png

再详看官网的描述:

image.png 基于官网的描述,得出高性能基于以下特点:

  1. 事件驱动 + 非阻塞 I/O
  2. 事件检查器的懒加载
  3. 零拷贝
  4. 单缓冲(内存与CPU利用极致优化)

详情可参考:HAProxy - 可靠的高性能 TCP/HTTP 负载均衡器

核心组件

Listener(监听器)

Listener 是 HAProxy 接收客户端连接的入口,它监听指定的端口和协议(HTTP/TCP),并将连接传递给 frontend。

Frontend(前端)

Frontend 定义了接收连接的规则,例如监听端口、ACL(访问控制列表)、请求的转发方式。它相当于一个请求分发控制器。

Backend(后端)

Backend 定义了请求的实际去向,包括一组服务器(server),以及负载均衡策略,如轮询(roundrobin)、最少连接(leastconn)、源地址哈希(source)等。

Server(后端服务器)

每个 backend 包含多个 server 实例,HAProxy 会根据设置的调度算法将请求分发到具体的 server。

反向代理

正向代理,反向代理,我之前总是记不清楚区别,其实只要记好了服务的对象不一样即可:

image.png

正向代理:对于服务端而言,他不知道请求来自哪个客户端,可以用于翻墙

反向代理:对于客户端而言,它不需要知道响应来自哪个服务端,一般用于多个服务水平部署的负载均衡

代理层级

基于上述的负载均衡算法,我们也能看出,Haproxy可以基于TCP和HTTP,而目前由于我们服务的特殊性,我们需要保持用户的长连接,尽量让用户连接到同一个服务上。而 HAProxy 在四层性能(如 TCP 长连接处理)上优于 Nginx,且支持更多七层算法(如 url_param),这可能就是为什么我们选择使用HAProxy来作为负载均衡的中间件。

而且HAProxy 支持运行时调整权重及慢启动,而 Nginx 需重启生效 。

参考