模块十_SpringCloud组件设计原理(上)

序言:

文章内容输出来源:拉勾教育Java高薪训练营。
本篇文章是学习课程中的一部分课后笔记

一、 Spring Cloud 简介

1、 Spring Cloud 是什么
  • Spring Cloud是⼀系列框架的有序集合(Spring Cloud是⼀个规范)
  • 开发服务发现注册、配置中⼼、消息总线、负载均衡、断路器、数据监控等
  • 利⽤Spring Boot的开发便利性简化了微服务架构的开发(⾃动装配)
2、 Spring Cloud 解决什么问题
  • ⽐如:
    微服务架构中的服务注册发现问题、⽹络问题(⽐如熔断场景)、统⼀认证安全授权问题、负载均衡问题、链路追踪等问题。
3、 Spring Cloud 核⼼组件
组件.png
体系结构.png
4、Spring Cloud 与 Dubbo 对⽐
  • Dubbo :基于RPC调⽤,体系的组件不全,不能够提供⼀站式解决⽅案,⽐如服务注册与发现需要借助于Zookeeper等实现。
  • Spring Cloud : 基于HTTP调用,提供了⼀站式服务化解决⽅案,且有Spring⼤家族背景。

二、Eureka 组件

1、Eureka服务注册中⼼
  • 服务注册中⼼本质上是为了解耦服务提供者和服务消费者。


    一般原理.png
  • 步骤:
    1)服务提供者启动;
    2)服务提供者将相关服务信息主动注册到注册中⼼;
    3)服务消费者获取服务注册信息:
    poll模式:服务消费者可以主动拉取可⽤的服务提供者清单
    push模式:服务消费者订阅服务(当服务提供者有变化时,注册中⼼也会主动推送更新后的服务清单给消费者)
    4)服务消费者直接调⽤服务提供者,另外,注册中⼼也需要完成服务提供者的健康监控,当发现服务提供者失效时需要及时剔除;

2、Eureka交互流程
交互流程.png
  • Eureka 包含两个组件:Eureka ServerEureka Client
    Eureka Client 是⼀个Java客户端,⽤于简化与Eureka Server的交互;
    Eureka Server 提供服务发现的能⼒;
    各个微服务启动时,会通过Eureka Client向Eureka Server 进⾏注册⾃⼰的信息(例如⽹络信息),Eureka Server会存储该服务的信息;

  • 每个Eureka Server同时也是Eureka Client,多个Eureka Server之间通过复制的⽅式完成服务注册列表的同步;

  • Eureka Client会缓存Eureka Server中的信息。
    即使所有的Eureka Server节点都宕掉,服务消费者依然可以使⽤缓存中的信息找到服务提供者。

3、 Eureka细节详解
  • Eureka的元数据有两种:
    标准元数据:主机名、IP地址、端⼝号等信息,这些信息都会被发布在服务注册表中,⽤于服务之间的调⽤;
    ⾃定义元数据:可以使⽤eureka.instance.metadata-map配置,符合KEY/VALUE的存储格式。这些元数据可以在远程客户端中访问;
instance:
 prefer-ip-address: true
 metadata-map:
 # ⾃定义元数据(kv⾃定义)
 cluster: cl1
 region: rn1
4、 ⾃我保护机制
  • 当⽹络分区故障发⽣时,微服务与Eureka Server之间⽆法正常通
    信,⽽微服务本身是正常运⾏的,此时不应该移除这个微服务,所以引⼊了⾃我保护机制。

  • 自我保护机制特点:
    1)不会剔除任何服务实例(可能是服务提供者和EurekaServer之间⽹络问题),保证了⼤多数服务依然可⽤;
    2)Eureka Server仍然能够接受新服务的注册和查询请求,但是不会被同步到其它节点上,保证当前节点依然可⽤,当⽹络稳定时,当前Eureka Server新的注册信息会被同步到其它节点中;
    3)在Eureka Server⼯程中通过eureka.server.enable-self-preservation配置可⽤关停⾃我保护,默认值是打开;

eureka:
 server:
 enable-self-preservation: false # 关闭⾃我保护模式(缺省为打开)
5、 EurekaClient启动过程要做什么事情:
  • 1)读取配置⽂件
  • 2)启动时从EurekaServer获取服务实例信息
  • 3)注册⾃⼰到EurekaServer(addInstance)
  • 4)开启⼀些定时任务(⼼跳续约,刷新本地服务缓存列表)

三、Ribbon负载均衡

1、关于负载均衡
  • 负载均衡⼀般分为服务器端负载均衡客户端负载均衡
    服务器端负载均衡:⽐如Nginx、F5这些,请求到达服务器之后由这些负载均衡器根据⼀定的算法将请求路由到⽬标服务器处理。
    客户端负载均衡:⽐如我们要说的Ribbon,服务消费者客户端会有⼀个服务器地址列表,调⽤⽅在请求前通过⼀定的负载均衡算法选择⼀个服务器进⾏访问,负载均衡算法的执⾏是在请求客户端进⾏。
    负载均衡.png
2、Ribbon负载均衡策略
负载策略.png
3、Ribbon部分原理
原理.png
  • 重点是经过一个拦截器
    之后执行RibbonLoadBalancerClient.execute()


    原理.png

四、Hystrix熔断器

1、雪崩效应
  • 微服务A调⽤微服务B和微服务C,微服务B和微服务C⼜调⽤其它的微服务,这就是所谓的“扇出”。
    如果扇出的链路上某个微服务的调⽤响应时间过⻓或者不可⽤,对微服务A的调⽤就会占⽤越来越多的系统资源,进⽽引起系统崩溃,所谓的“雪崩效应”;
    扇入扇出.png
2、雪崩效应问题解决方案
  • 服务熔断
    1)服务熔断重点在“断”,切断对下游服务的调⽤
    2)服务熔断和服务降级往往是⼀起使⽤的,如Hystrix。

  • 服务降级
    整体资源不够⽤了,先将⼀些不关紧的服务停掉,返回兜底数据。

  • 服务限流(核心业务不能降级时候)
    1)限制总并发数(⽐如数据库连接池、线程池)
    2)限制瞬时并发数(如nginx限制瞬时并发连接数)
    3)限制时间窗⼝内的平均速率(如Guava的RateLimiter、nginx
    的limit_req模块,限制每秒的平均速率)
    4)限制远程接⼝调⽤速率、限制MQ的消费速率等

3、 Hystrix简介(豪猪----->刺)

Hystrix主要通过以下⼏点实现延迟和容错:

  • 包裹请求:使⽤HystrixCommand包裹对依赖的调⽤逻辑。
  • 跳闸机制:当某服务的错误率超过⼀定的阈值时,Hystrix可以跳闸,停⽌请求该服务⼀段时间。
  • 资源隔离:Hystrix为每个依赖都维护了⼀个⼩型的线程池(舱壁模式)(或者信号量)。如果该线程池已满, 发往该依赖的请求就被⽴即拒绝,⽽不是排队等待,从⽽加速失败判定。
  • 监控:Hystrix可以近乎实时地监控运⾏指标和配置的变化,例如成功、失败、超时、以及被拒绝的请求等。
  • 回退机制:当请求失败、超时、被拒绝,或当断路器打开时,执⾏回退逻辑。回退逻辑由开发⼈员⾃⾏提供,例如返回⼀个缺省值。
  • ⾃我修复:断路器打开⼀段时间后,会⾃动进⼊“半开”状态。

五、Feign简介

  • Netflix开发的⼀个轻量级RESTful的HTTP服务客户端(⽤它来发起请求,远程调⽤的)
  • 本质:封装了Http调⽤流程,更符合⾯向接⼝化的编程习惯,类似于Dubbo的服务调⽤;
    (Feign = RestTemplate+Ribbon+Hystrix)
1、 Feign 特点:
  1. Feign可帮助我们更加便捷,优雅的调⽤HTTP API:不需要我们去拼接url然后调⽤restTemplate的api,在SpringCloud中,使⽤Feign⾮常简单,创建⼀个接⼝(在消费者--服务调⽤⽅这⼀端),并在接⼝上添加⼀些注解,代码就完成了;
  2. SpringCloud对Feign进⾏了增强,使Feign⽀持了SpringMVC注解(OpenFeign);
2、 Feign 对负载均衡的⽀持
  • Feign 本身已经集成了Ribbon依赖和⾃动配置;
  • Feign默认的请求处理超时时⻓1s,Feign⾃⼰有超时设置,如果配置Ribbon的超时,则会以Ribbon的为准;
3、Feign对熔断器的⽀持

1)开启Hystrix之后,Feign中的⽅法都会被进⾏⼀个管理了,⼀旦出现问题就进⼊对应的回退逻辑处理;
2)针对超时这⼀点,当前有两个超时时间设置(Feign/hystrix),熔断的时候是根据这两个时间的最⼩值来进⾏的,即处理时⻓超过最短的那个超时时间了就熔断进⼊回退降级逻辑;

4、Feign对请求压缩和响应压缩的⽀持
  • Feign ⽀持对请求和响应进⾏GZIP压缩,以减少通信过程中的性能损耗。
feign:
 compression:
 request:
 enabled: true # 开启请求压缩
 mime-types: text/html,application/xml,application/json # 设置压缩的数据类
型,此处也是默认值
 min-request-size: 2048 # 设置触发压缩的⼤⼩下限,此处也是默认值
 response:
 enabled: true # 开启响应压缩
5、Feign的⽇志级别配置
    1. 开启Feign⽇志功能及级别
// Feign的⽇志级别(Feign请求过程信息)
// NONE:默认的,不显示任何⽇志----性能最好
// BASIC:仅记录请求⽅法、URL、响应状态码以及执⾏时间----⽣产问题追踪
// HEADERS:在BASIC级别的基础上,记录请求和响应的header
// FULL:记录请求和响应的header、body和元数据----适⽤于开发及测试环境定位问题
@Configuration
public class FeignConfig {
 @Bean
 Logger.Level feignLevel() {
 return Logger.Level.FULL;
 }
}
    1. 配置log⽇志级别为debug
logging:
 level:
 # Feign⽇志只会对⽇志级别为debug的做出响应
 com.lagou.edu.controller.service.ResumeServiceFeignClient: debug

六、GateWay⽹关组件

1、 GateWay简介
  • 基于Spring5.0+SpringBoot2.0+WebFlux
    (基于⾼性能的Reactor模式响应式通信框架Netty,异步⾮阻塞模
    型)等技术开发,性能⾼于Zuul,官⽅测试,GateWay是Zuul的1.6倍;

  • Spring Cloud GateWay不仅提供统⼀的路由⽅式(反向代理)并且基于 Filter(定义过滤器对请求过滤,完成⼀些功能) 链的⽅式提供了⽹关基本的功能,例如:鉴权、流量控制、熔断、路径重写、⽇志监控等。

2、 GateWay架构中的位置
网关位置.png
3、GateWay核⼼概念
  • 路由(route): ⽹关最基础的部分,也是⽹关⽐较基础的⼯作单元。路由由⼀个ID、⼀个⽬标URL(最终路由到的地址)、⼀系列的断⾔(匹配条件判断)和* Filter过滤器(精细化控制)组
    成。如果断⾔为true,则匹配该路由。
  • 断⾔(predicates):参考了Java8中的断java.util.function.Predicate,开发⼈员可以匹配Http请求中的所有内容(包括请求头、请求参数等)(类似于nginx中的location匹配⼀样),如果断⾔与请求相匹配则路由。
  • 过滤器(filter):⼀个标准的Spring webFilter,使⽤过滤器,可以在请求之前或者之后执⾏业务逻辑。
3、 GateWay⼯作过程
  • GateWay核⼼逻辑:路由转发+执⾏过滤器链
    工作流程.png
  1. 客户端向Spring Cloud GateWay发出请求,然后在GateWay Handler Mapping中找到与请求相匹配的路由,将其发送到GateWay Web Handler;

  2. Handler再通过指定的过滤器链来将请求发送到我们实际的服务执⾏业务逻辑,然后返回。

  3. 过滤器之间⽤虚线分开是因为过滤器可能会在发送代理请求之前(pre)或者之后(post)执⾏业务逻辑。

  4. Filter在“pre”类型过滤器中可以做参数校验、权限校验、流量监控、⽇志输出、协议转换等,在“post”类型的过滤器中可以做响应内容、响应头的修改、⽇志的输出、流量监控等。

七、 Spring Cloud Config 分布式配置中⼼

1、 Config简介
  • Spring Cloud Config是⼀个分布式配置管理⽅案,包含了 Server端和 Client端两个部分。
结构示意图.png
  • Server 端:提供配置⽂件的存储、以接⼝的形式将配置⽂件的内容提供出去,通过使⽤@EnableConfigServer注解在 Spring boot 应⽤中⾮常简单的嵌⼊
  • Client 端:通过接⼝获取配置数据并初始化⾃⼰的应⽤
2、Config配置⾃动更新

实现⼀次通知处处⽣效

  • 方式一:⽤的是zk(存储+通知),zk中数据变更,可以通知各个监听的客户端,客户端收到通知之后可以做出相应的操作(内存级别的数据直接⽣效,对于数据库连接信息、连接池等信息变化更新的,那么会在通知逻辑中进⾏处理,⽐如重新初始化连接池)

  • 方式二:结合消息总线(Bus)实现分布式配置的⾃动更新(Spring CloudConfig+Spring Cloud Bus)

自动更新配置.png

八、Spring Cloud Stream消息驱动组件

1、Stream重要概念
  • Spring Cloud Stream 是⼀个构建消息驱动微服务的框架。
    类似于hibernate 统一了接口,关于底层mysql、Oracle等DB的差异屏蔽掉了。
  • Stream 本质:
    屏蔽掉了底层不同MQ消息中间件之间的差异,统⼀了MQ的编程模型,降低了学习、开发、维护MQ的成本。
结构图.png
2、Stream消息通信⽅式
  • Stream中的消息通信⽅式遵循了发布—订阅模式
    当⼀条消息被投递到消息中间件之后,它会通过共享的 Topic 主题进⾏⼴播,消息消费者在订阅的主题中收到它并触发⾃身的业务逻辑处理。
    这⾥所提到的 Topic 主题是Spring Cloud Stream中的⼀个抽象概念,⽤来代表发布共享消息给消费者的地⽅。在不同的消息中间件中, Topic 可能对应着不同的概念;
    ⽐如:在RabbitMQ中的它对应了Exchange、在Kakfa中则对应了Topic
3、Stream编程注解
image.png
4、Stream消息分组

在服务消费者端设置 spring.cloud.stream.bindings.input.group 属性,多个消费者实例配置为同⼀个group名称(在同⼀个group中的多个消费者只有⼀个可以获取到消息并消费)。

九、常⻅问题及解决⽅案

1、 Eureka 服务发现慢
  • Eureka 服务发现慢的原因主要有两个:
    ⼀部分是因为服务缓存导致的,另⼀部分是因为客户端缓存导致的。
缓存.png
  • 解决方案:
    将这些服务端缓存和客户端缓存的时间全部缩短后,我们通过调整参数的⽅式来尽量加快服务发现的速度,但是还是不能完全解决报错的问题,间隔时间设置为3秒,也还是会有间隔。
    所以我们⼀般都会开启重试功能,当路由的服务出现问题时,可以重试到另⼀个服务来保证这次请求的成功。
2、 Spring Cloud 超时设置问题
  • 在SpringCloud中,应⽤的组件较多,只要涉及通信,就有可能会发⽣请求超时。
  • 在 Spring Cloud 中,超时时间只需要重点关注 Ribbon 和 Hystrix 即可。
  1. Ribbon 如果采⽤的是服务发现⽅式,就可以通过服务名去进⾏转发,需要配置Ribbon的超时。
    Rbbon的超时可以配置全局ribbon.ReadTimeoutribbon.ConnectTimeout。也可以在前⾯指定服务名,为每个服务单独配置,⽐如 user-service.ribbon.ReadTimeout。

  2. Hystrix Hystrix全局超时配置就可以⽤default来代替具体的command名称;
    hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=3000
    @HystrixCommand 的话,可以⾃定义 commandKey。

  3. Feign Feign本身也有超时时间的设置,如果此时设置了Ribbon的时间就以Ribbon的时间为准,如果没设置Ribbon的时间但配置了Feign的时间,就以Feign的时间为准。
    Feign的时间同样也配置了连接超时时间(feign.client.config.服务名称.connectTimeout)和读取超时时间(feign.client.config.服务名称.readTimeout)。

你可能感兴趣的:(模块十_SpringCloud组件设计原理(上))