vlambda博客
学习文章列表

第三章 负载均衡LB服务之Haproxy

第三章  负载均衡LB服务之Haproxy

3.1 Haproxy简介

上一章,我们介绍了LVS负载均衡,其实在实际生产环境中,Linux系统中的LB功能还有haproxy、Nginx方向代理等多种工具可以实现。本章将介绍Haproxy的原理及配置。

3.1.1 负载均衡模式

LB功能在实现原理上,可以有传输层和应用层两种实现方式,从功能上讲,应用层的负载均衡方式会更全面、灵活一些。而Haproxy对于这两种方式都能支持,只需要在配置文件中指定工作模式即可。

应用层均衡模式,即http模式。是基于OSI第七层应用层完成转发的。除了能够把高并发的客户请求分流给多个节点外,还可以根据客户请求的资源不同,分配给内部不同的节点组。如:当客户请求访问www.rzz.com时,LB服务器分配给第一组节点处理,而客户访问www.rzz.com/bbs时,LB服务器分配给第二组节点处理。这样就可以实现对访问目标资源的分析与区别处理。

health模式:实例工作于health模式,其对入站请求仅响应“OK”信息并关闭连接,且不会记录任何日志信息;此模式将用于响应外部组件的健康状态检查请求;目前业讲,此模式已经废弃,因为tcp或http模式中的monitor关键字可完成类似功能

3.1.2 Haproxy特性

    Haproxy是一款以C语言编写、开源的负载均衡工具,并且免费使用、性能稳定。可提供负载均衡+高可用的集群服务。支持传输层和应用层代理。并且能够很好的与系统(尤其是类unix系统)、应用服务兼容。

从宏观上讲,Haproxy最大的特点就是支持更多的并发连接,在与LVS、Nginx的对比,Haproxy是支持并发数最多的,甚至可以与硬件均衡设备(如F5)相媲美,可支持到数以万计的并发。

Haproxy支持高并发的原理主要是haproxy采用了一种被称为事件驱动、单一进程模型的机制来处理客户请求。这种机制比较复杂,简单的讲,haproxy进程接收所有客户请求,并统一管理。我们打开网页后,对网页的任何操作都可被视为一个事件,如:页内链接、跳转、页内查询等。当发生事件后,进程会立即针对事件,分配系统资源(如cpu、内存资源),处理运行,结束后回收、释放资源。对于Haproxy进程而言,进程内部并不按照连接区分不同客户,任何客户请求Haproxy主进程都会一视同仁,调用可用资源来处理它。不太恰当的讲,这就类似于班主任管理一个班级,任何一名学员的请求,班主任都当做是班级事务处理,调动学校资源满足学员要求。

这种事件驱动,就与其他LB工具(LVS、Nginx)有明显区别,LVS和Nginx服务器接收到客户请求后,会为该客户连接分配独立的进程或线程做相应。而单个进程或线程占据的系统资源(cpu、内存)是固定的、有限的,用得了、用不了都给进程分配这么多,且不能超资源使用。这就决定了LVS和Nginx不能够合理、有效的占用所有系统空闲资源。而事件驱动就解决了这一问题,Haproxy进程可以更大限度的使用系统空闲资源,而且没有浪费,所以就更合理与优越。由于支持的并发数较大,所以haproxy可以更大限度的占满服务器所连接网络的带宽,有测试表明,haproxy可以占满约10Gbps的带宽,这是一个相当强劲的数据量。

事件驱动的缺点在于,在多核cpu的主机上,进程、事件在不同核上占据时间片时,需要更复杂的调度算法,需要更合理的管理并优化cpu各核时间片。当然,这些都是Haproxy开发者,或底层开发人员需要关心的问题,我们作用工具的使用者,只需要知道haproxy的大体原理的特性就好了。

再者,haproxy稳定性、安全性也较高,不仅可以监测故障节点,还支持对客户的拒绝连接。我们知道基于TCP协议规定,任何客户请求,服务器是不允许拒绝的(参照TCP三次握手),DOS攻击(拒绝服务攻击)就是基于TCP协议这个天生的硬伤实现的。而haproxy的可拒绝特性,能够很大程度上保护内部节点,过滤功能。这对很多小型站点对于DDOS(分布式拒绝服务攻击)的攻击起到了很好的保护作用。

3.1.3 Haproxy均衡算法

与LVS类似,Haproxy也支持多种均衡算法,总结看来共有八种算法可供选择:

1、roundrobin

基于权重的轮询算法,在服务器的处理时间保持均匀分布时,这是最平衡,最公平的算法。并且此算法是动态的,服务器的权重可以在运行时进行调整。但是,每个节点服务器最多支持4128个并发连接。

2、static-rr

基于权重进行轮询,与roundrobin类似,但为静态方法。在运行时调整其服务器权重不会生效,不过,其后端的节点服务器没有连接数限制

3、leastconn

最少连接数算法。新的连接请求被分配至具有最少连接数目的后端节点服务器。在有着较长时间会话的场景中推荐使用此算法,如LDAP环境、SQL访问频发时等;但是其并不太适用于较短会话的应用层协议,如HTTP。此算法也是动态的,可以在运行时调整其权重。

4、first

由第一个具有可用连接的服务器得到连接。即所有节点服务器将从最小到最大的id选择。一旦一个服务器到达它的最大连接数,下一个服务器将被使用。如果不定义每个服务器的maxconn参数(最大连接数),则这个算法是无意义的。使用这个算法的目的是尽量使用最小数量的服务器以便于其他服务器可以在非密集时段待机。这个算法将忽略服务器权重。

5、source

6、uri

对URI的左半部分(“?”标记之前的部分)或整个URI进行hash运算,并由服务器的总权重相除后派发至某匹配的服务器。这可以使得对同一个URI的请求总是被派发至某特定的服务器,除非服务器的权重总数发生了变化。此算法常用于代理缓存或反病毒代理以提高缓存的命中率。需要注意的是,此算法仅应用于HTTP后端服务器场景。其默认为静态算法,不过也可以使用hash-type修改此特性。

7、url_param

通过< argument>为URL指定的参数在每个HTTP GET请求中将会被检索。如果找到了指定的参数且其通过等于号”=”被赋予了一个值,那么此值将被执行hash运算并被服务器的总权重相除后派发至某匹配的服务器。此算法可以通过追踪请求中的用户标识进而确保同一个用户ID的请求将被送往同一个特定的服务器,除非服务器的总权重发生了变化。如果某请求中没有出现指定的参数或其没有有效值,则使用轮叫算法对相应请求进行调度。此算法默认为静态的,不过其也可以使用hash-type修改此特性。

8、hdr(< name>)

对于每个HTTP请求,通过<name>指定的HTTP首部将会被检索。如果相应的首部没有出现或其没有有效值,则使用轮询算法对相应请求进行调度。其有一个可选选项”use_domain_only”,可在指定检索类似Host类的首部时仅计算域名部分(比如通过www.baidu.com来说,仅计算”baidu”字符串的hash值)以降低hash算法的运算量。此算法默认为静态的,不过其也可以使用hash-type修改此特性。

   tips:URI与URL

URI,统一资源标志符(UniformResource Identifier, URI),表示的是web上每一种可用的资源,如 HTML文档、图像、视频片段、程序等都由一个URI进行定位的。如:https://blog.jiaozhu.com/qq_32595453/article/details/79516787。

URL,统一资源定位符,UniformResource Locator的缩写。URL是URI的一个子集。

从上面的例子来看,你可能觉得URI和URL可能是相同的概念,其实并不是,URI和URL都定义了资源是什么,但URL还定义了该如何访问资源。URL是一种具体的URI,它是URI的一个子集,它不仅唯一标识资源,而且还提供了定位该资源的信息。URI 是一种语义上的抽象概念,可以是绝对的,也可以是相对的,而URL则必须提供足够的信息来定位,是绝对的。