《微服务架构实战》读书笔记5-2 负载均衡和容错

上一文中主要写了微服务简介、注册中心简介、服务发现的两种方式,写的略有些粗糙。

Eureka简介(补)
书中有详细描述基于Eureka实现注册中心,Zookeeper和Eureka都可以以集群的形式向外提供服务。Zookeeper基于***的方式,选取leader用于写服务,而Eureka是一种去中心化的架构,无master/slave区分,采用Peer 投Peer对等通信。Eureka中,节点之间采用相互注册提高可用性,每个节点都可以看作其他节点的副本。
当某台Eureka服务节点宕机,来自客户端的请求会自动切换到其他server,宕机的服务节点重启后,再加入集群管理中。当节点接收请求时,基于replicateToPeer(节点间复制)将请求复制到其他Eureka server 知道的服务节点中。(保证服务可用)
节点启动,尝试从邻居节点获取所有实例注册信息,完成初始化。使用getEurekaServiceUrls()方法获取所有的节点,并且通过心跳续约的方式更新。使用案例后续会有补全(flag~)
回顾spring cloud的各组件运行流程:
  1. 所有请求都统一通过API网关(Zuul)来访问内部服务
  2. 网关接收到请求后,从注册中心(Eureka)获取可用服务
  3. 由Ribbon进行均衡负载后发送到具体的实例
  4. 微服务之间通过Feign进行通信处理业务
  5. Hystrix负责处理服务超时熔断
  6. Turbine监控服务间的调用和熔断相关指标。

本文内容
本文主要从概念上介绍服务负载均衡和服务容错

一、负载均衡
(一)负载均衡简介:
微服务架构下,后端服务都是以集群的形式提供,负载均衡模块的主要任务是将用户输入的流量(如网络请求)通过==负载均衡器==按照某种==负载均衡算法==,把流量均匀地分散到后端的多个服务器上,接收请求的服务器可以独立的响应请求,达到==负载分担==的目的。
(二)常见负载均衡模型
1. 服务端负载均衡:
通常我们所说的负载均衡都是服务端负载均衡。

核心都是维护一个可用的服务端清单,然后通过心跳机制来删除故障的服务端节点以保证清单中都是可以正常访问的服务端节点。当有用户请求到达时,负载均衡器从可用服务器节点中按某种配置好的规则选取一个服务节点处理客户端请求,这就是服务端负载均衡。

服务端负载均衡分为两类:
- 硬件负载:在服务器节点间安装专门用于负载均衡的设备实现,常见设备如F5。
- 软件负载: 在服务器上安装一些具有负载均衡功能的软件完成请求分发进而实现负载均衡,如Nginx

上述两种工作原理如图:


2. 客户端负载均衡:
相比于服务端负载均衡,客户端负载均衡的不同之处在与其存储服务清单的位置在每一个客户端节点中。客户端负载均衡的每一个客户端都会从注册中心获取一份自己想访问的服务清单。

在spring cloud中想使用负载均衡,只需开启@loadBalanced注解即可,这样客户端在发起请求时会先自行选择一个服务端,想该服务端发起请求,从而实现负载均衡。
详细过程如下图:

实现负载均衡的组件
Ribbon,一个基于Http和tcp的客户端负载均衡器。将Ribbon和Eureka一起使用,Eureka负责注册中心,Ribbon用户客户端负载均衡。Ribbon会从Eureka中获取服务端列表,然后进行轮询访问列表,从而达到负载均衡。客户端需要心跳机制维护列表清单,清除无效的服务节点。

常见负载均衡策略
- 简单轮询负载均衡
- 加权相应时间负载均衡
- 区域感知轮询负载均衡
- 随机负载均衡

负载均衡策略详细信息可以参考我的有道云笔记:
https://note.youdao.com/share/?id=1d671db020b43d0518f99a7a763bf1a0&type=note#/

Spring cloud负载实现
抽象类:AbstractLoadBalancerRule,里边主要定义了ILoadBalancer
基于choose方法获取服务实例
具体实现:
  • RandomRule:随机选择服务,生成随机数,作为下标值,获取服务实例
  • RoundRobinRule:定义一个计数器。while循环遍历服务清单,获取清单之前使用自增的方式获取服务节点下标,基于下标获取服务,每次循环计数器加1,如果连续10次都没有获取到服务则报警告。
  • RetryRule: 带有重试功能的负载均衡策略,其实现类为RoundRobinRule。每次调用RandomRule获取服务实例,获取到则正常返回,获取实例为null或已失效,则在失效时间之前不断进行尝试,如果到了deadline还没取到,在返回null。
  • WeightedResponseTimeRule:是RoundRobinRule的一个子类,对RoundRobinRule进行扩展。根绝每个实例的运行情况计算该实例的权重,选择实例是根据权重去挑选,从而实现更好的实例调用。
  • BestAvailable:继承自ClientConfigEnabledRoundRobinRule, 其内部定义了RoundRobinRule,采用RoundRobinRule的choose方法,在ClientConfigEnabledRoundRobinRule的基础上主要增加了根据loadBalancerStats中保存的服务实例状态信息,过滤掉失败的服务实例,然后找出并发请求最小的服务实例。如果loadBalancerStats为null,则采用父类ClientConfigEnabledRoundRobinRule的服务选取策略。
  • PredictBasedRule也是ClientConfigEnabledRoundRobinRule的一个子类,通过内部定义的过滤器过滤一部分服务实例清单,采用线性轮询方法从过滤出来的结果中选取实例。
  • ZoneAvoidanceRule:是PredictBasedRule的实现类,多了一个过滤条件。

Ribbon组件
是Netflix发布的云中间层服务开源项目,主要功能是提供客户侧软件负载均衡算法,将Netflix的中间层服务连接一起。
工作步骤:
1. 优先选择Eureka Server,优先选择在同一个Zone,且负载较少的Server;
2. 根据用户指定的策略,从Server取到的服务注册列表中选择一个地址。提供多种策略(轮询、随机、时间加权等  )

Feign组件:Spring Cloud NEtflix中,微服务之间基于http接口的形式暴漏自身服务。Feign是一个声明式的、模版话的HTTP客户端。基于Feign可以想使用本地方法一样来调用远端方法,感知不到这是http请求。

二、熔断机制简介
(一)背景
雪崩效应:是一种因服务提供者的不可用导致服务调用者的不可用,并将不可用逐渐放大的过程

雪崩效应形成过程
1. 服务提供者不可用
a)硬件故障:硬件损坏造成的服务器主机宕机, 网络硬件故障造成的服务提供者的不可访问
b)程序Bug:
c) 缓存击穿:缓存击穿一般发生在缓存应用重启, 所有缓存被清空时,以及短时间内大量缓存失效时. 大量的缓存不命中, 使请求直击后端,造成服务提供者超负荷运行,引起服务不可用
d)用户大量请求:在秒杀和大促开始前,如果准备不充分,用户发起大量请求也会造成服务提供者的不可用
2. 重试加大流量
a)用户重试:在服务提供者不可用后, 用户由于忍受不了界面上长时间的等待,而不断刷新页面甚至提交表单
b)代码逻辑重试: 服务调用端的会存在大量服务异常后的重试逻辑
3. 服务调用者不可用
a)同步等待造成的资源耗尽:当服务调用者使用同步调用 时, 会产生大量的等待线程占用系统资源. 一旦线程资源被耗尽,服务调用者提供的服务也将处于不可用状态, 于是服务雪崩效应产生了。
(二)解决方案
1. 服务熔断:般是指软件系统中,由于某些原因使得服务出现了过载现象,为防止造成整个系统故障,从而采用的一种保护措施,所以很多地方把熔断亦称为过载保护。很多时候刚开始可能只是系统出现了局部的、小规模的故障,然而由于种种原因,故障影响的范围越来越大,最终导致了全局性的后果。
2. 服务降级:当服务器压力剧增的情况下,根据当前业务情况及流量对一些服务和页面有策略的降级,以此释放服务器资源以保证核心任务的正常运行

感觉下边这篇文章讲的很详细(包括雪崩背景、服务熔断等相关概念,hystrix实现、执行流程等),上述关于熔断机制的内容引于此处

ps 下篇文章中会详细介绍hystrix的使用和实现
#笔记##读书笔记#
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务