spring boot下的配置文件application.yaml中属性spring.application.name=xxx在spring cloud中会被注册为服务名

高可用:减少不提供服务的时间

1. 服务治理

主要用来实现各个微服务实例的自动化注册与发现 [1-39]

服务注册

在服务治理框架中,会有一个注册中心,每个服务单元向注册中心登记自己提供的服务。通过注册中心互相注册可组成高可用集群。

服务发现

在服务治理框架下,服务间的调用不再通过具体指定的实例地址来实现,而是通过服务名发起请求调用实现。所以,服务调用方在调用提供方的接口时,并不清楚具体的服务实例地址。 需要客户端负载均衡。

基础架构

服务注册中心

提供服务注册与发现的功能

服务提供者

提供服务的应用,它将自己提供的服务注册到注册中心上,以供其它应用发现

服务消费者

消费者应用从服务注册中心获取服务列表,从而使消费者可以知道去何处调用其所需要的服务

很多时候,客户端及时服务提供者也是服务消费者

服务治理机制

描述从服务注册到服务调用,及各个单元所涉及的一些重要通信行为

服务提供者(客户端)

服务注册

“服务提供者”在启动时会通过发送REST请求的方式将自己注册到注册中心上,同时带上了自身服务的一些元数据信息。[1-53]

服务同步

当两个服务提供者分别注册到了两个不同的服务注册中心上,即他们的信息分别被两个服务注册中心所维护。由于服务注册中心之间因互相注册为服务,当服务提供者发送注册请求到一个服务注册中心时,它会将该请求转发给集群中相连的其它注册中心,从而实现注册中心之间的服务同步。

服务续约

在注册完服务后,服务提供者会维护一个心跳用来持续告诉注册中心仍在服务中,以防止被注册中心的“剔除服务”将该服务实例从服务列表中排除。可在配置文件中设置属性,有两个重要属性,1. 定义服务续约任务的调用时间间隔; 2. 定义服务实效的时间

服务消费者(客户端)

获取服务

启动服务消费者的时候,会发送一个REST请求给服务注册中心,获取上面注册的服务清单。获取服务清单是服务消费者的基础,所以在配置文件中,一定要将注册发现设置为true

服务调用

服务消费者在获取清单后,通过服务名可以获得具体提供服务的实例名和该实例的元数据信息。客户端可以根据自己的需求决定具体调用哪个实例,如通过Ribbon默认采用的轮询方式进行调用,实现客户端的负载均衡

服务下线

在系统运行期间面临的关闭或者重启某个实例,同时客户端不能调用关闭了的实例。因此,当服务实例正常的关闭时,发送一个服务下线的REST给注册中心。服务端收到请求后,将该服务状态设置为DOWN,并传播

服务注册中心(服务端)

失效剔除

当由于内存溢出或者网络故障使得服务不能正常工作,而服务注册中心并未收到“服务下线”的请求。为了从服务列表中将这些无法提供服务的实例剔除,服务注册中心会创建一个定时任务,默认每隔一段时间将当前清单中超时没有续约的服务剔除

自我保护

源码分析

[1-56]

对于服务注册中心、服务提供者、服务消费者这三个主要元素,后两者(客户端)在整个运行机制中是大部分通信行为的主动发起者,而注册中心主要是处理请求的接收者。

将一个普通的Spring Boot应用注册到注册中心或是从注册中心获取服务列表时,主要做了两件事:

  • 在应用主类上配置了@EnableDiscoveryClient注解
  • application.properties/yaml/yml中配置服务注册中心的位置,如eureka的eureka.client.serviceUrl.defaultZone参数

@EnableDiscoveryClient注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(EnableDiscoveryClientImportSelector.class)
public @interface EnableDiscoveryClient {/*** If true, the ServiceRegistry will automatically register the local server.* @return - {@code true} if you want to automatically register.*/boolean autoRegister() default true;
}

2. 客户端负载均衡

[1-74]

负载均衡是系统架构中的重要内容,因为负载均衡是对系统的高可用、网络压力的缓解和处理能力扩容的重要手段之一。分为硬件负载均衡(如F5)和软件负载均衡(如Nginx);

通过Spring Cloud Ribbon的封装,我们在微服务架构中使用客户端负载均衡调用非常简单,如下两步:

  • 服务提供者只需要启动多个服务实例并注册到一个注册中心或是多个相关联的服务注册中心
  • 服务消费者直接通过调用被@LoadBalanced注解修饰过得RestTemplate来实现面向服务的接口调用

RestTemplate详解

GET请求

有两个方法进行调用Get请求

  • getForEntity方法

该方法返回的是ResponseEntity,该对象是Spring 对 HTTP请相应的封装,其中主要存储了HTTP的几个重要元素,如HTTP请求状态码的枚举对象HttpStatus、在它的父类HttpEntity中还存储着HTTP请求的头信息对象HttpHeaders以及泛型类型的请求体对象。

  • getForObject方法

POST请求

PUT请求

DELETE请求

源码分析

负载均衡器

[1-91]

Spring Cloud中定义了LoadBalanceClient作为负载均衡器的通用接口,并且针对Ribbon实现了RibbonLoadBalanceClient,但是在具体实现客户端负载均衡时是通过Ribbon的ILoadBalancer接口实现的,具体实现类如下

AbstractLoadBalancer

BaseLoadBalancer

DynamicServerListLoadBalancer

ZoneAwareLoadBalancer

负载均衡策略

3. 服务容错保护:Spring Cloud Hystrix

在微服务架构中,将系统拆分成为了很多服务单元,各单元的应用间通过服务注册与订阅的方式相互依赖。由于每个单元都在不同的进程间中运行,依赖通过远程调用的方式执行,就有可能因为网络原因或是依赖服务自身问题出现调用故障或延迟,直接导致了调用方的对外服务也会出现延迟,若此时调用方的请求不断增加,最后就会因等待出现故障的依赖方响应形成任务积压,最终导致自身服务的瘫痪。

在微服务架构中,存在着那么多的服务单元,若一个单元出现故障,就很容易因依赖关系而引发故障的蔓延,最终导致整个系统的瘫痪。为了解决这样的问题,产生了断路器等一系列的服务保护机制。

在分布式架构中,当某个服务单元发生故障之后,通过断路器的故障监控,像调用方返回一个错误响应,而不是长时间的等待。这样就不会使得线程因调用故障服务被长时间占用不释放,避免了故障在分布式系统中的蔓延。

Spring Cloud Hystrix实现了断路器、线程隔离等一系列服务保护功能。该框架的目标在于通过控制那些访问远程系统、服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。Hystrix具备服务降级、服务熔断、线程和信号隔离、请求缓存、请求合并以及服务监控等强大功能。

  • 在服务消费者中引入依赖

    <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId><version>2.1.2.RELEASE</version>
    </dependency>
    
  • 在服务消费者主类上加上注解@EnableCircuitBreaker

    因为服务消费者上面已经有了@SpringBootApplication@EnableDiscoveryClient注解,因此可以直接在主类上使用组合注解@SpringCloudApplication

原理分析

工作流程

  1. 创建HystrixCommandHystrixObervableCommand对象

    构建对象,用来表示对依赖服务的操作请求,同时传递所有需要的参数。采用了 “ 命令模式 ” 来实现对服务调用操作的封装。

    • HystrixCommand: 用在依赖服务返回单个操作结果的时候
    • HystrixObervableCommand: 用在依赖的服务返回多个操作结果的时候
  2. 命令执行

  3. 结果是否被缓存

  4. 断路器是否打开

  5. 线程池/请求队列/信号量是否占满

  6. 请求依赖服务

  7. 计算断路器的健康度

  8. fall back处理

    当命令执行失败的时候,Hystrix会进入fallback尝试回退处理,也称之为服务降级。能够引起服务降级处理的情况有下面几种

    • 第4步,当前命令处于“熔断/短路”状态,断路器是打开的时候
    • 第5步,当前命令的线程池、请求队列或者信号量被占满的时候
    • 第6步,HystrixObervableCommand.construct() 或 HystrixCommand.run() 抛出异常的时候
  9. 返回成功的响应

断路器原理

依赖隔离

例如docker的“舱壁模式”,实现了进程的隔离,使得容器与容器之间不会互相影响。而Hystrix则使用该模式实现线程池的隔离,它会为每一个依赖服务创建一个独立的线程池,这样就算某个依赖服务出现延迟过高的情况,也只是对该依赖服务的调用产生影响,而不会拖慢其他的依赖服务。

4. 声明式服务调用:Spring Cloud Feign

基于Netflix Feign实现,整合了Ribbon和Hystrix,并且提供了一种声明式的Web服务客户端定义方式

  • 依赖

    <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    
  • 在主类上添加@EnableFeignClients注解,开启Spring Cloud Feign 功能

5. API网关服务:Spring Cloud Zuul

没有API网关服务的问题:

    1. 对后端微服务的请求,通过Nginx等设置的路由与负载均衡后,被转发到各个不同的服务实例中;而这些设施需要的正确的路由与分发请求,以及需要维护的路由规则以及服务实例列表会增加难度
    1. 对外服务的安全性。服务中需要有一定的权限校验机制,比如对用户登录状态的校验等。但是如果在每一个模块的接口中都需要这些校验逻辑,不得不在每个应用中都添加同样的校验。当此校验出现问题需要修改或者需要优化时,又需要为每一个模块进行修改,加重了开发、测试的任务

解决:

  • 路由与服务实例问题:Spring Cloud Zuul将自身注册为一个服务实例,同时获取注册中心中的其它服务的实例信息
  • 校验问题:校验机制与微服务本身的业务没有多大关系,因此可以将校验机制独立为一个单独的服务存在,被剥离和独立出来之后,可以再API网关服务上进行统一调用来对微服务接口做前置过滤,以实现对微服务接口的拦截的校验。

构建网关

请求路由

请求过滤

[1-226]

Spring Cloud Zuul两个核心功能介绍

  • 它作为系统的统一入口,屏蔽了系统内部各个微服务的细节
  • 可以与服务治理框架结合,实现自动化的服务实例维护以及负载均衡的路由转发
  • 实现接口权限校验与微服务业务逻辑的解耦
  • 通过服务网关中的过滤器,在各生命中期中去校验请求的内容,将原本在对外服务层做的校验.前移,保证了微服务的无状态性,同时降低了微服务的测试难度,让服务本身更集中关注业务逻辑的处理。

5.1 路由详解

5.2 过滤器详解

过滤器

过滤器可以说是Zuul实现API网关功能最为核心的部件,每一个进入Zuul的HTTP请求都会经过一系列的过滤器处理链得到请求响应并返回给客户端。

在Spring Cloud Zuul中是实现的过滤器必须包含4个基本特征:过滤类型、执行顺序、执行条件、具体操作。这些功能实际上是实现过滤功能要继承的抽象类ZuulFilter中,所要实现的抽象方法

String filterType();int filterOrder();boolena shouldFilter();Object run();

它们各自的含义与功能总结如下:

  • filterType:该函数需要返回一个字符串来代表过滤器的类型,而这个类型就是在HTTP请求过程中定义的各个阶段。在Zuul中默认定义了4种不同生命周期的过滤器类,集体如下

    • pre:在请求过滤之前被调用
    • routing:在路由请求时被调用
    • post:在routing和error过滤器之后被调用
    • error:处理请求时发生错误时被调用
  • filterOrder:通过int值来定义过滤器的执行顺序,数值越小优先级越高
  • shouldFilter:返回一个boolean值用来判断该过滤器是否要执行。可以通过指定该方法来指定过滤器的有效范围
  • run:过滤器的具体逻辑。在该函数中,可以实现自定义的过滤逻辑,来确定是否要拦截当前的请求,不对其进行后续的路由,或是在请求路由返回结果之后,对处理结果做一些加工等。

请求生命周期

Zuul中定义了4种不同的过滤器类型,覆盖了一个外部HTTP请求到达API网关,直到返回请求结果的全部生命周期。

核心过滤器

为了让API网关组件可以被更方便地使用,Spring Cloud Zuul在HTTP请求生命周期的各个阶段默认实现了一批核心过滤器,它们会在API网关服务启动的时候被自动加载和启用。位于org.springframework.cloud.netflix.zuul.filters包下

(Spring Cloud Version – Greenwich.SR1 – 2.1.1.RELEASE)

pre过滤器

[1-241]

  • ServletDetectionFilter:执行顺序为 -3,是最先被执行的过滤器。该过滤器总是会被执行,主要用来检测当前请求是通过Spring的DispatcherServlet处理请求的,还是通过ZuulServlet处理请求的。
  • Servlet30Wrapper:执行顺序为 -2 ,是第二个执行的过滤器。
  • Servlet30RequestWrapper
  • FormBodyWrapperFilter:执行顺序为 -1 , 是第三个执行的过滤器。该过滤器仅对两种请求生效,第一类是Content-Typeapplication/x-www-form-urlencoded,第二类是Content-Typemultipart/form-data并且是由Spring的DispatcherServlet处理的请求。
  • DebugFilter:执行属性为 1, 是第四个执行的过滤器。
  • PreDecorationFilter:执行顺序为 5 , 是pre阶段最后被执行的过滤器。

route过滤器

  • RibbonRoutingFilter:执行顺序为 10 ,是 route阶段第一个执行的过滤器。
  • SimpleHostRoutingFilter:100,第二个
  • SendForwardFilter:500,第三个

post过滤器

  • SendErrorFilter:执行顺序为 0 ,是 post阶段第一个执行的过滤器。
  • SendResponseFilter:执行顺序为 1000 , 是 post阶段最后执行的过滤器。

异常处理

禁用过滤器

通过设置配置文件中的配置内容:

zuul.<SimpleClassName>.<filterType>.disable=true# <SimpleClassName> : 过滤器的类名
# <filterType> : 过滤器类型
# 例 : zuul.AccessFilter.pre.disable=true

5.3 动态加载

微服务架构中,API网关担负着外部访问统一入口的重任,任何关闭应用和重启应用的操作都会使系统对外服务停止,这种事不允许的。

因此,应具备动态功能内部逻辑的能力,比如动态修改路由规则、动态添加/删除过滤器等

动态路由

6. 分布式配置中心:Spring Cloud Config / Apollo

用来为分布式系统中的基础设施和微服务应用提供集中化的外部配置支持,分为服务端与客户端两部分。其中服务端也称为分布式配置中心,它是一个独立的微服务应用,用来连接配置仓库并为客户端提供获取配置信息、加密/解密信息等访问接口;客户端是微服务架构中的各个微服务应用或基础设置,它们通过指定的配置中心来管理应用资源与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息。

7. 消息总线:Spring Cloud Bus

在微服务架构的系统中,通常会使用轻量级的消息代理来构建一个共用的消息主题让系统中的所有微服务实例都连接上来。由于该主题中产生的消息会被所有实例监听和消费,所以我们称之为消息总线。在总线上的各个实例都可以方便的广播一些需要让其它连接在该主题的实例都知道的消息,例如配置信息的变更或者其它一些管理操作等。

消息代理

是一种消息验证、传输、路由的架构模式。它在应用程序之间起到通信调度并最小化应用之间的依赖的作用,使得应用程序可以高效地解耦通信过程。

需要使用消息代理的场景:

  • 将消息路由到一个或多个目的地
  • 消息转化为其他的表现形式
  • 执行消息的聚集、消息的分解,并将结果发送到它们的目的地,然后重新组合响应返回给消息用户
  • 调用Web服务来检索数据
  • 响应事件或错误
  • 使用发布-订阅模式来提供内容或基于主题的消息路由

目前的开源产品:

  • ActiveMQ
  • Kafka
  • RabbitMQ
  • RocketMQ

RabbitMQ实现消息总线

基本概念

  • Broker:消息队列服务器的实体,它是一个中间件应用,负责接收消息生产者的消息,然后将消息发送至消息接收者或者其他的Broker。
  • Exchange:消息交换机,是消息第一个到达的地方,消息通过它指定的路由规则,分发到不同的消息队列中
  • Queue:消息队列,消息通过发送和路由之后最终到达的地方,到达Queue的消息即进入逻辑上等待消费的状态。每个消息都会被发送到一个或多个队列。
  • Binding:绑定,它的作用就是把Exchange 和 Queue按照路由规则绑定起来,也就是Exchange和Queue之间的虚拟连接
  • Routing Key:路由关键字,Exchange根据这个关键字进行消息投递
  • Virtual host:虚拟主机,它是对Broker的虚拟划分,将消费者、生产者和它们依赖的AMQP相关结构进行隔离,一般都是为了安全考虑。
  • Connection:连接,代表生产者、消费者、Broker之间进行通信的物理网络
  • Channel:消息通道,用于连接生产者和消费者的逻辑结构。在客户端的每个连接,可建立多个Channel,每个Channel代表一个会话任务,通过Channel可以隔离同一连接中的不同交互内容。
  • Producer:消息生产者,制造消息并发送消息的程序
  • Consumer:消息消费者,接收消息并处理消息的程序

Kafka 实现消息总线

8. 消息驱动的微服务:Spring Cloud Stream

9. 分布式事务跟踪:Spring Cloud Sleuth

文献

  1. Spring Cloud微服务实战 翟永超

Spring Cloud简单笔记相关推荐

  1. Spring Cloud 学习笔记(2 / 3)

    Spring Cloud 学习笔记(1 / 3) Spring Cloud 学习笔记(3 / 3) - - - 56_Hystrix之全局服务降级DefaultProperties 57_Hystri ...

  2. Spring Cloud 学习笔记(2 3)

    Spring Cloud 学习笔记(1 / 3) Spring Cloud 学习笔记(3 / 3) - - - 56_Hystrix之全局服务降级DefaultProperties 57_Hystri ...

  3. Spring Cloud 学习笔记(1 / 3)

    Spring Cloud 学习笔记(2 / 3) Spring Cloud 学习笔记(3 / 3) - - - 01_前言闲聊和课程说明 02_零基础微服务架构理论入门 03_第二季Boot和Clou ...

  4. Spring Cloud学习笔记—网关Spring Cloud Gateway官网教程实操练习

    Spring Cloud学习笔记-网关Spring Cloud Gateway官网教程实操练习 1.Spring Cloud Gateway介绍 2.在Spring Tool Suite4或者IDEA ...

  5. Spring Cloud学习笔记

    Spring Cloud学习笔记 相关代码地址:https://github.com/gongxings/spring-cloud-study.git 一.工程环境搭建 spring cloud版本: ...

  6. Spring Cloud学习笔记【十二】Hystrix的使用和了解

    Spring Cloud学习笔记[十二]Hystrix的使用和了解 Hystrix [hɪst'rɪks],中文含义是豪猪,因其背上长满棘刺,从而拥有了自我保护的能力.本文所说的Hystrix是Net ...

  7. Spring Cloud 学习笔记(3 3)

    Spring Cloud 学习笔记(1 / 3) Spring Cloud 学习笔记(2 / 3) - - - 108_Nacos之Linux版本安装 109_Nacos集群配置(上) 110_Nac ...

  8. Spring Cloud 学习笔记(3 / 3)

    Spring Cloud 学习笔记(1 / 3) Spring Cloud 学习笔记(2 / 3) - - - 108_Nacos之Linux版本安装 109_Nacos集群配置(上) 110_Nac ...

  9. Spring Cloud 学习笔记(四)-Spring Cloud Hystrix

    Spring Cloud 学习笔记(四)-Spring Cloud Hystrix 由于前一阵子项目的原因,今天才继续弄上,今天想学习一下Hystrix组件 这个组件还挺抽象的,最开始我一直没太明白, ...

最新文章

  1. python定义只有一个元素的元组
  2. 详解OTT与IPTV的不同之处
  3. 有限差分法FDM和有限元法FEA比较
  4. excel切片器显示错误_Office 2016中报表用户的新Excel切片器功能
  5. 如何录制回放测试用例并且添加检查点?
  6. OpenCV版本与EmguCV版本匹配问题
  7. 关于Unicode字符集
  8. 李宏毅:1天搞懂深度学习,我总结了 300 页 PPT(附思维导图PPT)
  9. 网站smtp服务器,SMTP服务器
  10. Atom markdown-pdf 插件错误 Markdown-pdf: Error. Check console for more information.
  11. C#开源代码Newbeecoder.UI控件库极力推荐
  12. 重装系统后,一直卡在天涯若比邻蓝屏
  13. 在质疑声中,81岁的丁肇中或将证实“反物质世界”的存在
  14. win10商店下载主题壁纸提取
  15. !function(){}() 什么意思
  16. navicat 重置 mysql 表ID为1
  17. 新唐 Nuvoton NUC029 入门 点亮板载LED
  18. vst开启语音服务器,VST语音遥控器体验记
  19. 润盈益通保本型理财产品优势
  20. 成都计算机系统维护专业中专,成都计算机应用专业中专招生简章

热门文章

  1. 3天1W赞的程序员学习路线,入门进阶都非常实用
  2. java服务器常见状态码
  3. flutter widget super(key: key)的作用(五)
  4. getc与fgetc的区别
  5. 浙江大学 PAT 编程初级2
  6. IDEA打包JavaWeb的War包并部署到Tomcat
  7. 合并m3u8文件 okfun文件夹 .ok文件
  8. ATK-HC05蓝牙模块的详细说明
  9. Ubuntu 20.04自动挂载NFS失败
  10. 【组合数学】36军官问题