当前位置: 首页 > 科技观察

分布式-必知的负载均衡

时间:2023-03-14 09:57:10 科技观察

最近有个小伙伴在后台留言,让我写一篇关于负载均衡的文章,说网上其实有很多文章,每次都觉得一个某篇文章不错,但是有一次过一段时间,我什么都不记得了。那么今天我们就用生活中的故事来说说负载均衡。文章的某些部分可能有点啰嗦,但是为了让大家更好的理解,我也是下了一番功夫,真心希望大家能够掌握知识。什么是负载均衡?负载均衡,英文名称LoadBalance,意思是平衡负载(工作任务),并将其分配给多个运行单元运行,如FTP服务器、Web服务器、企业核心应用服务器和其他主任务服务器等.,从而配合完成工作任务。负载均衡通常有两个目的:分担压力和提供冗余(也可以理解为备份)。如果你对上面的生活案例还不理解,我们继续以生活案例为例:在高速公路出口处,如果只有一个出口,某天突然出现大量车辆(假设大家都有未办理ETC)在此高速出口下高速。比如有几百人要下高速,但是下高速要交过路费,每辆车至少要耽误几分钟。几百辆车!!!这意味着后者可能要等待几个小时。如果有很多出口呢?那就不用等那么久了。如果增加一个出口,这时候两个出口可以共用车辆下高速,收费员的速度就会被分摊。3号车看到1号车应该快点,然后追上1号车,如果再增加n,效果可想而知。但是太多了,好像造成了资源的浪费。一天进出很多个出口的车辆不多。如果多了就浪费了,所以我们一般看到的大部分都是两个,应急用无可厚非。“我们把司机理解为负载均衡器,可以根据前方路况判断走哪个出口。判别法可以理解为负载均衡算法。”我们技术领域的术语叫做冗余。我可以将收费员的速度理解为我们系统中一项服务的性能。技术领域用一张图来形容我们技术领域的负载均衡:把生活中的场景和技术领域一起理解起来更爽快。注:集群是指部署同一个App应用服务的多个节点。集群的主要目的是分担压力。负载均衡器(系统)可以理解为指挥官。当有请求到来时,commander按照一定的方法将请求传递给集群中的某个服务。指挥官可以通过多种方式将请求分配给集群中的某个服务。随机给、排队、谁响应谁快等方式构成负载均衡算法。以上类比只是个人理解。负载均衡类型DNS(DomainNameSystem域名系统)作为一种将域名和IP地址相互映射的分布式数据库,可以让人们更方便地访问互联网。DNS使用TCP和UDP的53端口,目前每级域名的长度限制为63个字符,域名总长度不能超过253个字符。DNS是最简单和最常见的负载平衡方法。一般用于实现“地理级别”的负载均衡。比如北方人进北京机房,南方人进广州机房,西方人进成都机房。DNS负载均衡的本质是DNS可以解析同一个域名,返回不同的IP地址。例如:https://www.sina.com.cn/北方用户使用时会解析为10.210.1.12(北京机房)返回,使用时返回14.213.164.27(广州机房)南方用户。简单DNS图的优点配置简单,无成本负载均衡的工作交给了DNS服务器,省去了管理的麻烦。缺点添加和修改记录需要一定的时间才能生效(因为DNS会缓存A记录)。一旦服务器坏掉需要下线,即使修改了A记录,也需要很长时间才能生效。在此期间,DNS仍会将域名解析到离线服务器,最终导致用户访问失败。负载不能按需分配,DNS不知道每台服务器的真实负载,所以负载效果不是很好。实际情况:在实际项目部署中,我们一般会对一些服务器使用DNS解析,使用域名解析作为第一级负载均衡。然后在服务器中使用nginx负载均衡作为二级负载均衡。硬件负载平衡硬件负载平衡是一种通过单独的设备实现负载平衡的功能。这类设备有点类似于路由器交换机,或者可以理解为负载均衡的基础网络设备。目前业界有两种硬件负载均衡:F5和A10。这种设备性能好,功能强大,但是价格可以用昂贵来形容。一般只有银行、国有企业等大而富有的企业才会考虑使用这种设备开会。我只在银行见过F5。至于A10,没接触过就不会撤了。优势功能强大:全面支持各级负载均衡,支持多种负载均衡算法,支持全局负载均衡。性能好:一般软件负载均衡可以支持10万+并发,但是硬件负载均衡可以支持10万以上并发。稳定性高:因为是商业产品,经过了很好严格的测试,已经大规模使用,所以稳定性非常高。安全性高:硬件负载均衡设备除了处理负载均衡外,还具有防火墙和抗DDOS攻击的作用。缺点:贵:记得银行花几百万买F5,据说还有更贵的,价格可想而知。可扩展性差:硬件设备可以根据业务进行配置,但不能进行扩展和定制。软件负载均衡软件负载均衡是通过负载均衡软件实现负载均衡功能。常见的负载均衡软件有LVS、Nginx。其中,LVS是Linux内核的四层负载均衡。四层和七层的区别在于它们的协议和灵活性不同。Nginx是7层负载均衡器,支持HTTP和E-mail协议,而LVS是4层负载均衡器,所以和协议无关,基本上所有的应用都可以,比如:聊天,数据库等下面是Nginx负载均衡的简单示意图:优点Nginx是用C语言编写的,同一个web服务器占用资源和内存少,性能高。当nginx服务器启动时,会产生一个master进程,master进程会fork出多个worker进程,由worker线程处理客户端的请求。Nginx支持高并发。每个worker子进程都是独立平等的。当有客户端请求时,worker进程公平竞争,抢到它的worker进程将请求提交给后端服务器。当后端服务器没有及时响应时,工作进程会继续接收下一个请求。当之前的请求有响应时,会触发一个事件。工作进程会继续之前的执行,直到响应结束。一个请求不会被两个工作进程执行。Nginx支持反向代理(用户感知的访问称为正向代理,如访问youtube,用户不敏感的访问称为反向代理,如负载均衡),支持七层负载均衡(扩展负载均衡的好处)。Nginx是异步非阻塞处理请求(第三点确认),使用epollandqueue方式,apache是??阻塞处理请求。Nginx处理静态文件速度快(原因:nginx模块化程度高,易于配置,nginx是单进程多线程的)。缺点与apache相比,不稳定。由于是单进程多线程,进程死亡会影响到很多用户。负载均衡有什么用?“流量分配”负载均衡可以分配多台主机的流量,提高用户系统的业务处理能力,提高服务可用性。段请求被分发到同一个后端服务器。「HealthCheck」支持自定义健康检查方式和频率,可以定时检查后端主机的运行状态,提供故障转移,实现高可用;“负载均衡”解决并发压力,提升应用处理性能(增加吞吐量,加强网络处理能力);通过增加或减少服务器数量来提高可扩展性,以提供网站可扩展性(expandability);完善安全和安全防护,对负载均衡器做一些过滤,黑白名单,防盗链等处理;常用的负载均衡算法轮训负载均衡系统收到请求后,按照一定的顺序将请求分发给服务器。轮训是一种不关注服务器状态的简单负载均衡算法策略。优点:如果服务器都正常的话,那么轮训是最理想的,因为这会让每个服务得到等量的请求,可谓“雨露连连”。缺点:上面说的有些理想化,但现实往往不是那样的,现实还是很骨感的,线上系统经常会出现各种问题,比如:当一个服务器挂了,轮训算法就拿不准了关心服务器的状态,会导致大量请求到一个已经挂掉的服务器,导致系统不可用,造成用户流失。还有一个常见的问题就是有的服务器响应快有的响应慢(比如32核服务器和16核服务器),而轮训算法没有关注对应的速度,所以会导致很多服务请求响应慢慢地。简单这会导致糟糕的用户体验,甚至可能由于响应时间慢而导致其他系统崩溃。加权轮询负载均衡系统根据服务器权重将请求任务分配给相应的服务器。这里的权重一般是根据系统硬件配置静态配置的。动态计算更适合业务,但复杂度与简单的循环训练相比。只是高了很多。加权轮训是轮训的一种特殊方法。主要目的是解决服务器处理能力差异的问题。比如集群中有的服务器有32个核心,而有的老系统有16个核心。理论上,我们可以对它们进行加权配置值,即32核服务器的处理能力是16核服务器的2倍,负载均衡算法的权重比例调整为2:1,允许更多的请求分配给32核服务器。加权轮训解决了轮训算法中基于服务器配置差异更好分配任务的问题。实际上仍然存在无法根据服务器状态差异分配请求任务的问题。最低负载优先级负载系统将请求分配给当前负载最低的服务器。这里的负载可以根据不同的请求类型和业务处理场景,用不同的指标来衡量。比如下面的场景,LVS这个四层网络负载均衡设备,可以通过连接数来判断服务器的状态。服务器连接数越大,服务器的压力就越大。Nginx,一个7层网络负载均衡系统,可以根据HTTP请求的数量来判断服务器的状态(Nginx内置的负载均衡算法不支持这种方式,需要自行扩展)。如果我们自己开发一个负载均衡系统,可以根据业务特点选择衡量系统压力的指标。如果CPU密集,可以通过CPU负载来衡量系统压力;如果是IO密集型,可以通过IO负载来衡量系统压力。最低负载优先算法解决了循环训练算法中无法感知服务器状态的问题,但是它带来的代价是复杂度增加很多,例如:最少链接数的算法首先需要负载系统统计每台服务器当前简历的链接,其应用场景仅限于负载均衡器收到的任何请求都会转发给服务器处理。否则,如果负载均衡器系统和服务有一个固定的连接池,这个算法就不适用了。LVS可以使用该算法进行负载均衡,但是通过连接池链接数据库Mysql集群的负载均衡系统不适合使用该算法进行负载均衡。优先级最低的CPU负载均衡算法,要求负载均衡系统以一定的方式收集每台服务器的具体CPU负载,同时判断是1分钟负载标准还是10分钟或15-分钟负荷标准,不存在1分钟肯定比15分钟好或差。不同业务的最佳时间间隔也不同。如果时间间隔太短,容易造成频繁的波动。如果时间间隔过长,可能会导致峰值到来时响应变慢。负载优先级最低的算法板可以完美解决循环训练算法的不足,而且由于负载均衡系统采用负载优先级最低的算法后需要感知服务器当前的运行状态,这也造成了很多的成本增加。对于开发者来说,round-robin训练算法可能只需要很短的代码就可以实现,但是最低负载优先级算法需要大量的代码来实现。最低负载优先级似乎解决了round-robin训练的缺点,但由于其复杂度的增加,实际使用的比例不如round-robin训练或round-robin加权算法。性能负载最好的最低优先级算法从服务器的角度分配请求,而性能最优的算法从客户端的角度分配请求,先把请求分配给处理速度最快的服务器,这样实现对客户端最快的响应。实际上,性能优先级类似于最低负载优先级。他们都需要感知服务器的状态。不同的是,最佳性能是以响应时间为标准的,服务器状态是从外部感知的。同样实现复杂度也很高。主要体现在以下几个方面:负载均衡系统需要收集每个请求的响应时间。如果处理大量的请求,这个收集加上响应时间本身的统计也会消耗系统的性能。为了减少这种统计消耗,可以采用抽样的方式进行统计,即不需要对所有服务器的所有请求次数进行完全统计,而是对部分任务的响应时间进行抽样统计,以估算出某个任务的响应时间总体要求。采样统计虽然可以降低性能消耗,但是却增加了很多实现的复杂度,因为需要确定合适的采样率。如果采样率太低,数据就会正确,如果采样率高,也会造成性能消耗。找到合适的采样率的复杂性也是可以想象的。无论是全部统计还是抽样统计,都需要选择合适的周期。30秒是最佳表现还是1分钟?目前没有标准的周期,在具体的业务场景中进行决策。你觉得复杂吗?,尤其是线上系统需要不断调试,然后找出一个相对合适的标准。Hash负载均衡系统根据请求中的某些关键字进行哈希计算,将相同的值分配给同一台服务器。这样做的目的是为了满足特定的业务需求,比如:将一个IP地址的请求分配给同一台服务器处理,适合有事务和会话的业务。例如:当我们通过浏览器登录网上银行时,会产生一个session信息。该会话是临时的,关闭浏览器后将失效。网银后台不需要持久化session信息,只需要在某个服务器上临时保留session即可,但需要保证用户在存在期间每次请求访问的都是同一台服务器会议。这种业务场景是通过源地址哈希来实现的。IDhash:将某个ID所代表的业务分配给同一个服务器处理,例如:userIdsessionid。在上面的网银登录例子中,可以使用sessionidhash来达到用户在同一个session中每次都访问同一个服务器的目的。负载均衡算法应用Dubbo中使用了哪些负载均衡算法?RandomLoadBalance(随机算法,默认)RoundRobinLoadBalance(权重循环训练算法)LeastActionLoadBalance(最少主动调用算法)ConsistentHashLoadBalance(一致性Hash方法)nginx中使用的类图选择了哪些负载均衡算法?"roundrobin(default)":轮循,将请求轮流分配给各个后台服务器,默认的负载均衡方式。适用于后台机器性能一致的情况。挂机的机器可以自动从服务列表中删除。“weight”:根据权重将请求分发到不同的机器,指定轮询概率,权重与访问比例成正比,用于后端服务器性能参差不齐的情况。例如:upstreambakend{server192.168.0.14weight=10;server192.168.0.15weight=10;}"IP_hash":根据请求者ip的hash值将请求发送给后台服务器,可以保证请求来自同样的ip打在固定的机器上,session问题就可以解决了。例如:upstreambakend{ip_hash;server192.168.0.14:88;server192.168.0.15:80;}"url_hash(third-party)":根据请求的url的hash值将请求分到不同的机器,当后台服务器缓存时效率高。例如:在upstream添加hash语句,server语句中不能写其他参数如权重,hash_method就是使用的hash算法。"fair(third-party)":按照后台响应时间分配请求,响应时间短的请求分配多。例如:upstreambackend{serverserver1;serverserver2;fair;}总结我们用生活中的故事来讲述负载均衡,什么是负载均衡,负载均衡的作用,负载均衡的种类,负载均衡算法的种类,还有我们的Dubbo以及负载均衡算法在nginx中的应用。本文转载自微信公众号《Java后端技术全栈》,可通过以下二维码关注。转载本文请联系Java后端技术全栈公众号。