SpringCloud、CloudAlibaba学习笔记

文章目录

SpringCloud

微服务架构

微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间相互调用、互相配合,为用户提供最终的价值。每个服务运行在其独立的进程中,服务与服务之间采用轻量级的通信机制互相协作(通常是基于HTTP协议的RESTful API)。每个服务都围绕着具体业务进行构建,并且能够被独立的部署到生产环境、类生产环境等。另外,应当尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建。


分布式微服务架构体系

服务注册与发现 服务调用 服务熔断 负载均衡 服务降级 服务消息队列

配置中心管理 服务网关 服务监控 全链路追踪 自动化构建部署 服务定时任务调度操作

服务注册中心:Eureka、Zookeeper、Consul、Nacos

服务调用:LoadBalance、Ribbon

服务调用:OpenFeign

服务降级:Hystrix、resilience4j、sentienl

服务网关:gateway

服务配置:Config、Nacos

服务总线: Bus、Nacos
在这里插入图片描述


SpringCloud

分布式微服务架构的一站式解决方案,是多种微服务架构落地技术的集合体,俗称微服务全家桶。


RestTemplate

RestTemplate提供了多种便捷访问远程http服务的方法,是一种简单便捷的访问RESTful服务的模版类,是Spring提供的用于Rest服务的客户端模版工具集。

使用restTemplate访问restful接口非常的简单粗暴无脑。

(url, requestMap, ResponseBean.class)这三个参数分别代表

REST请求地址、请求参数、HTTP响应转换被转换成的对象类型。


服务治理

服务治理主要是针对分布式服务框架的微服务,处理服务之间的调用依赖关系、故障监控与处理,可以实现服务调用、负载均衡、容错等,实现服务注册和发现。

需要服务治理等原因:

  1. 过多的服务URL配置困难
  2. 负载均衡分配节点压力过大的情况下,需要部署集群
  3. 服务依赖混乱,启动顺序不清晰
  4. 过多服务,导致性能指标分析难度较大,需要监控
  5. 故障定位于排查难度较大

服务注册与发现

服务注册:将某个服务的模块信息(服务的地址端口等)注册到服务注册中心。

服务发现:新注册的这个服务模块能够及时的被其他调用者发现。不管是服务新增或服务删减都能实现自动发现。

注册中心:

在服务注册与发现中,有一个注册中心。当服务器启动的时候,会把当前自己服务器的信息 比如 服务地址通讯地址等以别名方式注册到注册中心上。另一方(消费者|服务提供者),以该别名的方式去注册中心上获取到实际的服务通讯地址,然后再实现本地RPC调用RPC远程调用框架核心设计思想:在于注册中心,因为使用注册中心管理每个服务与服务之间的一个依赖关系(服务治理概念)。在任何rpc远程框架中,都会有一个注册中心(存放服务地址相关信息(接口地址))

集群避免单点故障

服务注册和服务发现的难点:

  1. 集群:得组成集群,这样单台出现故障,不至于服务宕机
  2. 数据同步:组合了集群,得要数据同步
  3. 强一致性:数据同步,在多台服务上要有一致性的要求,保证数据不会出现不一致的情况
  4. 高并发高可用:要能保证请求量比较大的情况下,服务还能保持高可用
  5. 选举机制:在有集群和数据同步以及一致性的要求下,得有一个master来主持整个运作,需要一个选举机制,确保选举公平和稳定。
  6. 分布式:如何支撑分布式上的不同环境的机器互联。

Eureka服务注册与发现

Eureka采用了CS的设计架构,Eureka Server 作为服务注册功能的服务器,它是服务注册中心。而系统中的其他微服务,使用 Eureka的客户端连接到 Eureka Server并维持心跳连接。这样系统的维护人员就可以通过 Eureka Server 来监控系统中各个微服务是否正常运行。

Eureka包含两个组件:Eureka Server和Eureka Client

(1)Eureka Server 提供服务注册服务

各个微服务节点通过配置启动后,会在EurekaServer中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观看到。

(2)EurekaClient 通过注册中心进行访问

是一个Java客户端,用于简化Eureka Server的交互,客户端同时也具备一个内置的、使用轮询(round-robin)负载算法的负载均衡器。在应用启动后,将会向Eureka Server发送心跳(默认周期为30秒)。如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,EurekaServer将会从服务注册表中把这个服务节点移除(默认90秒)

服务发现Discovery:

对于注册进Eureka里面的微服务,可以通过服务发现来获得该服务的信息

@EnableDiscoveryClient

Eureka自我保护:

保护模式主要用于一组客户端和Eureka Server之间存在网络分区场景下的保护。一旦进入保护模式,Eureka Server将会尝试保护其服务注册表中的信息,不再删除服务注册表中的数据,也就是不会注销任何微服务。

一句话:某时刻某一个微服务不可用了,Eureka不会立刻清理,依旧会对该微服务的信息进行保存。

Eureka满足了CAP里面的AP分支


CAP是什么

C:Consistency(强一致性)
A:Availability(高可用性)
P:Partition tolerance(分区容错性)

CAP理论关注粒度是数据,而不是整体系统设计的策略
最多只能同时较好的满足两个。

CAP理论的核心是:一个分布式系统,不可能同时很好的满足一致性,可能用和分区容错性这三个需求;因此,根据CAP原理,将NoSQL数据库分成了满足CA原则,满足CP原则和满足AP原则,三大类:
CA-单点集群,满足一致性,可用性的系统,通常在可扩展性上不太强大。
CP-满足一致性,分区容错的系统,通常性能不是特别高。
AP-满足可用性,分区容错的系统,通常对一致性要求略低一些。

分布式架构中 必须包含P, 基本上都是AP或CP


Eureka集群

在这里插入图片描述

微服务RPC远程服务调用最核心的是什么

高可用,试想你的注册中心只有一个only one, 它出故障了那就呵呵( ̄▽ ̄)"了,会导致整个为服务环境不可用,所以

解决办法:搭建Eureka注册中心集群 ,实现负载均衡+故障容错


Zookeeper服务注册与发现

Zookeeper是一个分布式协调工具,可以实现注册中心功能。

Zookeeper的服务节点是临时节点,服务断开后,心跳检测发现服务消失,会将节点清除。


Consul服务注册与发现

简介

Consul是一套开源的分布式服务发现和配置管理系统,由HashiCorp公司用GO语言开发。

提供了微服务系统中的服务治理、配置中心、控制总线等功能。这些功能中的每一个都可以根据需要单独使用,也可以一起使用以构建全方位的服务网格,总之Consul提供了一种完整的服务网格解决方案。

它具有很多的优点。包括:基于raft协议,比较简洁;支持健康检查,同时支持HTTP协议和DNS协议,支持跨数据中心的WAN集群,提供图形界面 跨平台Linux、Mac、Win


能干嘛

服务发现:提供HTTP和DNS两种发现方式;

健康监测:支持多种方式,HTTP、TCP、Docker、Shell脚本定制化监控;

KV存储:Key、Value存储方式;

多数据中心:Consul支持多数据中心;

可视化Web界面


三个注册中心的异同点

Eureka、Zookeeper、Consul三个组件 作为注册中心的异同点

在这里插入图片描述

AP(Eureka的自我保护机制,保证了A,高可用)

CP(Zookeeper / Consul 临时节点,宕机及时剔除,无法保证A )

此处见 尚硅谷 cloud2020脑图


Ribbon负载均衡服务调用

SpringCloud Ribbon是基于Netflix Ribbon 实现的一套客户端负载均衡的工具。

简单的说,Ribbon是Netflix发布的开源项目,主要功能是提供 客户端的软件负载均衡算法和服务调用。

Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,就是在配置文件中列出Load Balancer(简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器。我们很容易使用Ribbon实现自定义的负载均衡算法。

一句话:负载均衡 + RestTemplate调用

LB负载均衡是什么

简单的说就是将用户的请求平摊的分配到多个服务上,从而达到系统的HA(高可用)

常见的负载均衡有软件 Nginx、LVS、硬件F5等

集中式LB nginx、F5等

进程内LB Ribbon

Ribbon本地负载均衡客户端 VS Nginx服务端负载均衡区别

Nginx是服务器负载均衡,客户端所有请求都会交给nginx,然后由nginx实现转发请求。即负载均衡是由服务端实现的。

Ribbon本地负载均衡,在调用微服务接口的时候,会在注册中心上获取信息服务列表之后缓存到JVM本地,从而在本地实现RPC远程服务调用技术。

一句话:Nginx是实现服务器的负载均衡,而Ribbon是实现服务(一个服务下有多个提供者)的负载均衡。


Ribbon核心组件IRule

IRule:根据特定算法,从服务列表中选取一个要访问的服务

在这里插入图片描述

在这里插入图片描述


Ribbon负载均衡算法

原理

负载均衡算法:rest接口第几次请求数 % 服务器集群总数量 (取余数)= 实际调用服务器位置下标,每次服务重启动后 rest 接口计数从1开始。


OpenFeign服务接口调用

概述

Feign是一个声明式的WebService客户端,让编写WebService客户端变得非常容易,只需创建一个接口并在接口上添加注解即可。

Feign也支持可拔插式的编码器和解码器。SpringCloud对Feign进行了封装,使其支持了SpirngMVC标准注解和HttpMessageConverters。Feign可以与Eureka和Ribbon组合使用以支持负载均衡。


Feign能干嘛

Feign旨在使编写Java Http 客户端变得更容易。

前面在使用 Ribbon + RestTemplate 时,利用 RestTemplate 对 http 请求的封装处理,形成了一套模版化的调用方法。但是在实际开发中,由于对服务依赖的调用可能不止一处,

往往一个接口会被多处调用,所以通常都会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用。

所以,Feign在此基础上做了进一步封装,由他来帮助我们定义和实现依赖服务接口的定义。

在Feign的实现下,我们只需创建一个接口并使用注解的方式来配置它(以前是Dao接口上面标注@Mapper注解,现在是一个微服务接口上面标注一个Feign注解即可),即可完成对服务提供方的接口绑定,简化了使用SpringCloud Ribbon时,自动封装服务调用客户端的开发量。

Feign集成了Ribbon

利用Ribbon维护了服务提供者的服务列表信息,并且通过轮询实现了客户端的负载均衡。而与Ribbon不同的是,

通过Feign只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用。


Feign 和 OpenFeign两者区别

在这里插入图片描述


OpenFeign的使用

pom依赖、主启动类 @EnableFeignClients、Service接口 + @FeignClient注解

Feign自带负载均衡配置项


OpenFeign超时控制

OpenFeign集成了Ribbon,Ribbon的默认超时连接时间、读超时时间都是1秒,如果OpenFeign没有设置对应的超时时间,那么将会采用Ribbon的默认超时时间。请求超过时间就会报错。

两种解决方案:

  1. 设置OpenFeign的超时时间(推荐)

    default设置的是全局超时时间,对所有的openFeign接口服务都生效

feign:
  client:
    config:
      ## default 设置的全局超时时间,指定服务名称可以设置单个服务的超时时间
      default:
        connectTimeout: 5000
        readTimeout: 5000
  1. 设置Ribbon的超时时间(不推荐)
ribbon:
  # 值的是建立链接所用的时间,适用于网络状况正常的情况下, 两端链接所用的时间
  ReadTimeout: 5000
  # 指的是建立链接后从服务器读取可用资源所用的时间
  ConectTimeout: 5000

OpenFeign日志增强

OpenFeign虽然提供了日志增强功能,但是默认是不显示任何日志的,我们可以自己配置日志的级别,对Feign接口的调用情况进行监控和输出。

openFeign的日志级别如下:

  • NONE:默认的,不显示任何日志;
  • BASIC:仅记录请求方法、URL、响应状态码及执行时间;
  • HEADERS:除了BASIC中定义的信息之外,还有请求和响应的头信息;
  • FULL:除了HEADERS中定义的信息之外,还有请求和响应的正文及元数据。

配置类配置OpenFeign日志级别、yml中设置接口日志级别


Hystrix断路器

分布式系统面临的问题

复杂分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免地失败。


服务雪崩

多个微服务之间调用的时候,假设微服务A调用微服务B和微服务C,微服务B和微服务C又调用其它的微服务,范围越来越广,链路越来越长,这就是所谓的“扇出”(像一把扇子展开)。如果扇出的链路上某个微服务的调用响应时间过长或者不可用,对微服务A的调用就会占用越来越多的系统资源,进而引起系统崩溃,所谓的“雪崩效应”。

对于高流量的应用来说,单一的后端依赖可能会导致所有服务器的所有资源都在几秒钟内饱和。比失败更糟糕的是,这些应用程序还可能导致服务之间的延迟增加,备份队列,线程和其它系统资源紧张,导致整个系统发生更多的级联故障。这些都表示需要对故障和延迟进行隔离和管理以便单个依赖关系的失败,不能取消整个应用程序或系统。所以,通常当发现一个模块下的某个实例失败后,这时候这个模块依然还会接收流量,然后这个有问题的模块还调用了其它的模块,这样就会发生级联故障,或者叫雪崩。


Hystrix是什么

Hystrix是一个用于处理分布式系统的延迟容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,Hystrix能够保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。

“断路器”本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个符合预期的、可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方法无法处理的异常,这样就保证了服务调用方的线程不会被长时间、 不必要地占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。

服务降级、服务熔断、服务限流、接近实时的监控


服务降级

fallback

服务器繁忙,请稍后重试,不让客户端等待并立即返回一个友好提示,fallback。向调用方返回一个符合预期的、可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方法无法处理的异常。

哪些情况会触发服务降级:程序运行异常、超时、服务熔断触发服务降级、线程池/信号量打满也会导致服务降级


服务熔断

break

类似于保险丝,达到最大服务访问后,直接拒绝访问,拉闸限电,然后调用服务降级的方法并返回友好提示。

服务降级 -> 服务熔断 -> 恢复调用链路


熔断机制概述

熔断机制是应对雪崩效应的一种微服务链路保护机制。当扇出链路的某个微服务出错不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回错误的响应信息。

当检测到该节点微服务调用响应正常后,恢复调用链路。 (自我修复)

在SpringCloud框架里,熔断机制通过 Hystrix 实现。Hystrix会监控微服务间调用的状况,当失败的调用到一定的阈值,缺省是5秒内20次调用失败,就会启动熔断机制。熔断机制的注解是 @HystrixCommand


原理

在这里插入图片描述

保险丝 open后,会自我修复(half open),直到成功success,进入close状态


熔断类型

熔断关闭:熔断关闭不会对服务进行熔断;

熔断打开:请求不再进行调用当前服务,内部设置时钟一般为 MTTR(平均故障处理时间),当打开时长达到所设时钟则进入半熔断状态;

熔断半开:部分请求根据规则调用当前服务,如果请求成功且符合规则,则认为当前服务恢复正常,关闭熔断。


断路器起作用

在这里插入图片描述

涉及到断路器的三个重要参数:快照时间窗、请求总数阈值、错误百分比阈值。

  1. 快照时间窗:断路器确定是否打开需要统计一些请求和错误数据,而统计的时间范围就是快照时间窗,默认为最近的10秒;
  2. 请求总数阈值:在快照时间窗内,必须满足请求总数阈值才有资格熔断。默认为20,意味着在10秒内,如果该hystrix命令的调用次数不足20次,即使所有的请求都超时或其他原因失败,断路器都不会打开;
  3. 错误百分比阈值:当请求总数在快照时间窗内超过了阈值,比如发生了30次调用,如果在这30次调用中,有15次发生了超时异常,也就是超过50%的错误比,在默认设定50%阈值情况下,这时候就会将断路器打开。

断路器开启关闭的条件

1)当满足一定的阈值的时候(默认是10秒内超过20个请求次数)

2)当失败率达到一定的时候(默认10秒内超过50%的请求失败)

3)到达以上阈值,断路器将会开启

4)当开启的时候,所有请求都不会进行转发

5)一段时间之后(默认是5秒),这个时候断路器是半开状态,会让其中一个请求进行转发。如果成功,断路器会关闭,若失败,继续开启。重复步骤4和5。


断路器打开之后
  1. 再有请求调用的时候,将不会调用主逻辑,而是直接调用降级 fallback。通过断路器,实现了自动地发现错误并将降级逻辑切换为主逻辑,减少响应延迟的效果。

  2. 原来的主逻辑如何恢复?

    对于这一问题,hystrix也为我们实现了自动恢复功能。

    当断路器打开,对主逻辑进行熔断之后,hystrix会启动一个休眠时间窗,在这个时间窗口期内,降级逻辑会临时的成为主逻辑,当休眠时间窗到期,断路器将进入半开状态,释放一次请求到原来的主逻辑上,如果此次请求正常返回,那么断路器将闭合,主逻辑恢复,如果这次请求依然有问题,断路器继续进入打开状态,休眠时间窗重新计时。


服务限流

flowlimit

秒杀高并发等操作,严禁一窝蜂的过来拥挤,大家排队,一秒钟N个,有序进行。


Hystrix工作流程

9步

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PbJxVdIf-1658223942923)(/Users/wangzeqi/Library/Application Support/typora-user-images/image-20220619190647270.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lDTj7fIJ-1658223942926)(/Users/wangzeqi/Library/Application Support/typora-user-images/image-20220619190745212.png)]


服务监控HystrixDashBoard

Hystrix提供了准实时的调用监控(Hystrix Dashboard),Hystrix会持续地记录所有通过Hystrix发起的请求的执行信息,并以统计报表和图形的形式展示给用户,包括每秒执行多少请求多少成功,多少失败等。Netflix通过hystrix-metrics-event-stream项目实现了对以上指标的监控。Spring Cloud也提供了Hystrix Dashboard的整合,对监控内容转化成可视化界面。


Gateway网关

简介

cloud全家桶中有个很重要的组件就是网关,在1.x版本中采用的都是Zuul,但在2.x版本中,zuul的升级一直跳票,SpringCloud最后自己研发了一个网关代替Zuul,那就是SpringCloud Gateway。

Gateway是原 zuul1.x版的替代。

Gateway是在Spring生态系统之上构建的API网关服务,基于Spring 5,Spring Boot 2和 Project Reactor等技术。

Gateway旨在提供一种简单而有效的方式来对API进行路由,以及提供一些强大的过滤器功能, 例如:熔断、限流、重试等

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QUpgcoYq-1658223942929)(/Users/wangzeqi/Library/Application Support/typora-user-images/image-20220620224854209.png)]

**一句话:**SpringCloud Gateway 使用的 Webflux 中的 reactor-netty 响应式编程组件,底层使用了 Netty 通讯框架。


作用

反向代理、鉴权、流量控制、熔断、日志监控等。

image-20220620225420398

为什么选择Gateway

  1. Netflix不太靠谱,zuul2.0一直跳票,迟迟不发布

    一方面是因为Zuul1.0已经进入了维护阶段,而且Gateway是SpringCloud团队研发出来的,是亲儿子产品,值得信赖。而且很多功能Zuul都没有用起来。非常的简单快捷。

    Gateway是基于异步非阻塞模型上进行开发的,性能方面不需要担心。虽然Netflix早就发布了最新的Zuul2.x,但SpringCloud貌似没有整合计划。而且Netflix相关组件都宣布进入维护期,不知前景如何。

    多方面综合考虑 GateWay是很理想的网关选择。

  2. SpringCloud 具有如下特性

    基于Spring Framework5,Project Reactor 和 SpringBoot 2.0进行构建;

    动态路由:能够匹配任何请求属性;

    可以对路由指定 Predicate(断言)和 Filter(过滤器);

    集成Hystrix的断路器功能;

    集成SpringCloud服务发现功能;

    易于编写的 Predicate(断言)和 Filter(过滤器);

    请求限流功能;

    支持路径重写;

  3. SpringCloud GateWay 与 Zuul 的区别

    1)Zuul1.x,是一个基于阻塞 I/O的 API GateWay

    2)Zuul1.x 基于Servlet2.5使用阻塞架构,它不支持任何长连接(如WebSocket),Zuul的设计模式和 Nginx较像,每次I/O操作都是从工作线程中选择一个执行,请求线程被阻塞到工作线程完成,但是差别是Nginx用C++实现,Zuul用Java实现,而JVM本身会有第一次加载较慢的情况,使得Zuul的性能相对较差。

    3)Zuul2.x理念更先进,想基于Netty非阻塞和支持长连接,但SpringCloud目前还没有整合。Zuul2.x的性能较Zuul1.x有较大的提升。在性能方面,根据官方提供的基准测试,SpringCloud GateWay的 RPS(每秒请求数)是Zuul的 1.6 倍。

    4)SpringCloud GateWay 建立在 Spring Framework 5、Project Reactor 和 Spring Boot2之上,使用非阻塞API。

    5)SpringCloud GateWay 还支持 WebSocket 长连接,并且与Spring紧密集成拥有更好的开发体验。


Zuul模型和GateWay模型

Zuul1.x模型

SpringCloud中所集成的Zuul版本,采用的是Tomcat容器,使用的是传统的Servlet IO处理模型。

image-20220621105409834

上述模型的缺点:

servlet是一个简单的网络IO模型,当请求进入servlet container时,servlet container就会为其绑定一个线程,在并发不高的场景下这种模型是适用的。但是一旦高并发(比如抽风用jemeter压),线程数量就会上涨,而线程资源代价是昂贵的(上线文切换,内存消耗大)严重影响请求的处理时间。在一些简单业务场景下,不希望为每个request分配一个线程,只需要1个或几个线程就能应对极大并发的请求,这种业务场景下servlet模型没有优势。

所以Zuul 1.X是 基于 servlet 之上的一个阻塞式处理模型 ,即 spring 实现了处理所有request请求的一个servlet(DispatcherServlet)并由该servlet阻塞式处理处理。所以Springcloud Zuul无法摆脱servlet模型的弊端。


GateWay模型

GateWay是基于WebFlux。

传统的Web框架,比如说:struts2,springmvc等都是基于Servlet API与Servlet容器基础之上运行的。

但是在Servlet3.1之后有了异步非阻塞的支持 。而WebFlux是一个典型非阻塞异步的框架,它的核心是基于Reactor的相关API实现的。相对于传统的web框架来说,它可以运行在诸如Netty,Undertow及支持Servlet3.1的容器上。非阻塞式+函数式编程(Spring5必须让你使用java8)

Spring WebFlux 是 Spring 5.0 引入的新的响应式框架,区别于 Spring MVC,它不需要依赖Servlet API,它是完全异步非阻塞的,并且基于 Reactor 来实现响应式流规范。


三大核心概念

Route路由

路由是构建网关的基本模块,它由ID,目标URI,一系列的断言和过滤器组成,如果断言为true则匹配该路由;


Predicate断言

参考的是Java8的 java.util.function.Predicate

开发人员可以匹配 HTTP请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由;


Filter过滤

指的是Spring框架中GateWayFilter的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改;


总结

web请求,通过一些匹配条件,定位到真正的服务节点。并在这个转发过程的前后,进行一些精细化控制;

predicate就是我们的匹配条件;

而filter,就可以理解为一个无所不能的拦截器。有了这两个元素,再加上目标uri,就可以实现一个具体的路由了;


GateWay工作流程

客户端向 Spring Cloud Gateway 发出请求。然后在 Gateway Handler Mapping 中找到与请求相匹配的路由,将其发送到 Gateway Web Handler。

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

过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前(“pre”)或之后(“post”)执行业务逻辑。

Filter在“pre”类型的过滤器可以做参数校验、权限校验、流量监控、日志输出、协议转换等,

在“post”类型的过滤器中可以做响应内容、响应头的修改,日志的输出,流量监控等有着非常重要的作用。

核心逻辑

路由转发 + 执行过滤器链


网关路由两种配置方式

在配置文件yml中配置

代码中注入RouteLocator的Bean


实现动态路由

默认情况下,GateWay会根据注册中心注册的服务列表,以注册中心上微服务名为路径创建动态路由进行转发,从而实现动态路由的功能。

在yml配置文件中,将路由的url 配置为注册中心中的服务名,如:

uri: 
	lb://serviceName

需要注意的是,uri的协议为 lb,表示启用 GateWay 的负载均衡功能。

lb 是SpringCloud GateWay在微服务中自动为我们创建的负载均衡uri


Predicate的使用

通过断言来匹配路由

Route Predicate Factories 有多种不同的匹配规则,详见尚硅谷脑图;

总结:Predicate就是为了实现一组匹配规则,让请求过来找到对应的 Route进行处理;


Filter的使用

路由过滤器可以用于修饰进入的 HTTP 请求和返回的 HTTP响应,路由过滤器只能指定路由进行使用。

SpringCloud GateWay内置了多种路由过滤器,他们都由 GateWayFilter的工厂类来产生。

Filter的生命周期: pre、post

种类:GateWayFilter、GlobalFilter

自定义过滤器

implements GlobalFilter, Ordered
  // 重写方法
  @Override
  public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {}


  // 过滤器顺序定义
	@Override
	public int getOrder() {
    return FilterOrderConst.AGREEMENT_FILTER_ORDER;
	}

作用:全局日志记录、统一网关鉴权等


SpringCloud Config

概述

分布式配置中心

微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中会出现大量的服务。由于每个服务都需要必要的配置信息才能运行,所以一套集中式的、动态的配置管理设施是必不可少的。

SpringCloud提供了ConfigServer来解决这个问题,我们每一个微服务自己带着一个application.yml,上百个配置文件的管理…


是什么

image-20220623163246535

SpringCloud Config为微服务架构中的微服务提供集中化的外部配置支持,配置服务器为各个不同微服务应用的所有环境提供了一个中心化的外部配置。

SpringCloud Config分为服务端和客户端两部分

服务端也称为 分布式配置中心,它是一个独立的微服务应用,用来连接配置服务器并为客户端提供获取配置信息,加密/解密信息等访问接口。

客户端则是通过指定的配置中心来管理应用资源,以及与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息。配置服务器默认采用git来存储配置信息,这样就有助于对环境配置进行版本管理,并且可以通过git客户端工具来方便的管理和访问配置内容。


能干嘛

集中管理配置文件

不同环境不同配置,动态化的配置更新,分环境部署比如 dev/test/prod/beta/release

运行期间动态调整配置,不再需要在每个服务部署的机器上编写配置文件,服务会向配置中心统一拉取自己的信息

当配置发生变动时,服务不需要重启即可感知到配置的变化并应用新的配置

将配置信息以REST接口的形式暴露 (post、curl访问刷新均可)


Config服务端配置

yml 连接远程配置中心 git仓库

配置读取规则

/{label}/{application}-{profile}.yml
http://host:port/master/config-dev.yml

label:分支(branch)

name:服务名

profiles:环境(dev/test/prod)

最终实现用 SpringCloud Config 通过 GitHub 获取配置信息


Config客户端配置

关于bootstrap.yml 和 application.yml

application.yml 是用户级的资源配置项

bootstrap.yml 是系统级的配置,优先级更高

Spring Cloud会创建一个“Bootstrap Context”,作为 Spring 应用的Application Context的 父上下文 。初始化的时候,Bootstrap Context负责从 外部源 加载配置属性并解析配置。这两个上下文共享一个从外部获取Environment

Bootstrap属性有高优先级,默认情况下,它们不会被本地配置覆盖。 Bootstrap contextApplication Context有着不同的约定,*所以新增了一个bootstrap.yml文件,保证Bootstrap ContextApplication Context配置的分离。

要将Client模块下的application.yml文件改为bootstrap.yml,这是很关键的,

因为bootstrap.yml是比application.yml先加载的。bootstrap.yml优先级高于application.yml


Config客户端动态刷新

避免每次更新配置都都要重新启动客户端微服务,采用动态刷新的方式

POM引入 actuator 监控

yml 暴露监控端口

@RefreshScope注解实现动态刷新

主动发送post请求,刷新服务,必须是POST请求

curl -X POST "http://localhost:3355/actuator/refresh"

SpringCloud Bus消息总线

概述

分布式自动刷新配置功能

SpringCloud Bus 配合 SpringCloud Config 使用可以实现配置的动态刷新。

是什么

SpringCloud Bus 是用来将分布式系统的节点与轻量级系统链接起来的框架,它整合了 Java 的事件处理机制和消息中间件的功能。

SpringCloud Bus 目前支持两种消息代理: RabbitMQ 和 Kafka。

作用

Spring Cloud Bus能管理和传播分布式系统间的消息,就像一个分布式执行器,可用于广播状态更改、事件推送等,也可以当作微服务间的通信通道。

image-20220714173933062

SpringCloud Bus动态刷新全局广播

必须先具备良好的 RabbitMQ环境

设计思想

利用消息总线触发一个服务端 ConfigServer 的 /bus/refresh 端点,而刷新所有客户端的配置

一次修改,广播通知,处处生效。

image-20220714231223122

SpringCloud Bus动态刷新定点通知

不想全部通知,只想定点通知

指定具体某一个实例生效,而不是全部

image-20220714232000142

SpringCloud Stream消息驱动

是什么

SpringCloud Stream 是一个构建消息驱动微服务的框架,高度可伸缩。

应用程序通过 inputs 或者 outputs 来与 SpringCloud Stream中的 binder 对象交互。

通过我们配置来binding(绑定) ,而 Spring Cloud Stream 的 binder对象负责与消息中间件交互。

所以,我们只需要搞清楚如何与 Spring Cloud Stream 交互就可以方便使用消息驱动的方式。

通过使用Spring Integration 来连接消息代理中间件以实现消息事件驱动。

Spring Cloud Stream 为一些供应商的消息中间件产品提供了个性化的自动化配置实现,引用了发布-订阅、消费组、分区的三个核心概念。

目前仅支持 RabbitMQ、Kafka

**一句话:**屏蔽底层消息中间件的差异,降低切换成本,统一消息的编程模型。比如说,我们用到了RabbitMQ 和 Kafka,由于两个消息中间件的架构不同,存在差异性。我们在实际项目开发中选择了其中的一种,后面的业务需求,若想往另一种消息队列进行迁移,这时候由于前者已和系统耦合,很多东西需要推倒重新做,这时候就可以使用 SpringCloud Stream 给我们提供了解耦的方式。

设计思想

标准MQ

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X6zqzFpL-1658223942931)(/Users/wangzeqi/Library/Application Support/typora-user-images/image-20220715103137505.png)]

关于标准的MQ:

  1. 生产者/消费者之间靠消息媒介传递信息内容 Message
  2. 消息必须走特定的通道 消息通道 MessageChannel
  3. 消息通道里的消息如何被消费,谁负责收发处理

消息通道 MessageChannel 的子接口 SubscribableChannel,由 MessageHandler 消息处理器所订阅。

为什么使用 CloudStream

比方说我们用到了RabbitMQ和Kafka,由于这两个消息中间件的架构上的不同,像RabbitMQ有exchange,kafka有Topic和Partitions分区。

这些中间件的差异性导致我们实际项目开发给我们造成了一定的困扰,我们如果用了两个消息队列的其中一种,后面的业务需求,我想往另外一种消息队列进行迁移,这时候无疑就是一个灾难性的, 一大堆东西都要重新推倒重新做 ,因为它跟我们的系统耦合了,这时候springcloud Stream给我们提供了一种解耦合的方式。

image-20220715104436457
Binder

通过定义绑定器作为中间层,完美地实现了 应用程序与消息中间件细节之间的隔离

Stream对消息中间件的进一步封装,可以做到代码层面对中间件的无感知,甚至于动态的切换中间件(rabbitmq切换为kafka),使得微服务开发的高度解耦,服务可以关注更多自己的业务流程。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CCdqgak7-1658223942933)(/Users/wangzeqi/Library/Application Support/typora-user-images/image-20220715115740960.png)]

通过定义绑定器Binder作为中间层,实现了应用程序与消息中间件细节之间的隔离。

Binder可以生成Binding,Binding用来绑定消息容器的生产者和消费者,它有两种类型,INPUT和OUTPUT,INPUT对应于消费者,OUTPUT对应于生产者。

INPUT对应于消费者, OUTPUT对应于生产者

Stream中的消息通信方式遵循了发布-订阅模式

Topic主题进行广播

在RabbitMQ就是 Exchange、在Kafka中就是 Topic

SpringCloud Stream标准流程

Binder:很方便的连接中间件,屏蔽差异

Channel:通道,是队列 Queue的一种抽象,在消息通讯系统中就是实现存储和转发的媒介,通过Channel对队列进行配置

Source 和 Sink

参照对象是Spring Cloud Stream 自身来讲的话,从Stream 发布消息就是输出,接受消息就是输入。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w1kOTMXP-1658223942937)(/Users/wangzeqi/Library/Application Support/typora-user-images/image-20220715180548641.png)]

编码API和常用注解

image-20220715183113973

分组消费和持久化

同时启动两个消费者服务,一个生产者服务,运行后会存在两个问题:

  1. 重复消费问题
  2. 消息持久化问题 (没理解)

通过 分组来解决

案例:订单系统中做订单系统集群部署,集群从RabbitMQ获取订单信息,如果一个订单同时被两个服务获取到,那么就会造成数据错误,即重复消费。

使用SpringCloud Stream中的消息分组来解决

在Stream中,处于同一个 group中的多个消费者是竞争关系,这样就能够保证消息只会被其中一个应用消费一次。

而不同组 是可以全面消费的(重复消费)

同一组内发生竞争关系,只有其中一个服务可以消费。

原理

微服务应用放置于同一个group中,就能够保证消息只会被其中一个应用消费一次。

不同组是可以消费的,同一个组内会发生竞争关系,只有其中一个可以消费,从而避免了重复消费。

同一个组内的服务会进行轮询分组,每次只有一个消费者来消费。

SpringCloud Sleuth分布式请求链路跟踪

解决哪些问题

在微服务框架中,一个由客户端发起的请求在后端系统中会经过多个不同的服务节点调用来协同产生最后的请求结果,每一个前段请求都会形成一条复杂的分布式服务调用链路,链路中的任何一环出现高延时或错误都会引起整个请求的失败。

因此,有必要知道每一步调用的耗时、整个链路调用的步骤、耗时。

对于大型的系统,多节点、长链路调用,就需要有一套监控链路和跟踪的组件,即SpringCloud Sleuth。

是什么

SpringCloud Sleuth提供了一套完整的服务跟踪的解决方案

在分布式系统中提供追踪解决方案并且兼容支持了 zipkin

Sleuth 负责收集整理数据,zipkin负责展现数据

搭建链路监控

zipkin 安装

原理

完整的调用链路:表示请求链路,一条链路通过 Trace Id 唯一标识,Span标识发起的请求的请求信息,各Span通过parent id 关联起来。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xhEFe9to-1658223942942)(/Users/wangzeqi/Library/Application Support/typora-user-images/image-20220717111904027.png)]

原理

多个span id 组成一个 trace id

上图简化版:

每个span,通过 parent id 关联起来,一个 trace id 组成一条完整的链路,链路上的各个span关联。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x97zX1ZP-1658223942944)(/Users/wangzeqi/Library/Application Support/typora-user-images/image-20220717111946437.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cWJnRppO-1658223942948)(/Users/wangzeqi/Library/Application Support/typora-user-images/image-20220717112001516.png)]

Trace: 类似于树结构的Span集合,表示一条调用链路,存在唯一标识 (树的根节点)

span:表示调用链路来源,通俗的理解 span就是一次请求信息 (叶子节点)


SpringCloud Alibaba

Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。

依托 Spring Cloud Alibaba,您只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接入阿里微服务解决方案,通过阿里中间件来迅速搭建分布式应用系统。

此外,阿里云同时还提供了 Spring Cloud Alibaba 企业版 微服务解决方案,包括无侵入服务治理(全链路灰度,无损上下线,离群实例摘除等),企业级 Nacos 注册配置中心和企业级云原生网关等众多产品。

主要功能

  • 服务限流降级:默认支持 WebServlet、WebFlux、OpenFeign、RestTemplate、Spring Cloud Gateway、Zuul、Dubbo 和 RocketMQ 限流降级功能的接入,可以在运行时通过控制台实时修改限流降级规则,还支持查看限流降级 Metrics 监控。
  • 服务注册与发现:适配 Spring Cloud 服务注册与发现标准,默认集成了 Ribbon 的支持。
  • 分布式配置管理:支持分布式系统中的外部化配置,配置更改时自动刷新。
  • 消息驱动能力:基于 Spring Cloud Stream 为微服务应用构建消息驱动能力。
  • 分布式事务:使用 @GlobalTransactional 注解, 高效并且对业务零侵入地解决分布式事务问题。
  • 阿里云对象存储:阿里云提供的海量、安全、低成本、高可靠的云存储服务。支持在任何应用、任何时间、任何地点存储和访问任意类型的数据。
  • 分布式任务调度:提供秒级、精准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务。同时提供分布式的任务执行模型,如网格任务。网格任务支持海量子任务均匀分配到所有 Worker(schedulerx-client)上执行。
  • 阿里云短信服务:覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道。

组件

Sentinel:把流量作为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

Nacos:一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。

RocketMQ:一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的、高可靠的消息发布与订阅服务。

Seata:阿里巴巴开源产品,一个易于使用的高性能微服务分布式事务解决方案。

Alibaba Cloud OSS: 阿里云对象存储服务(Object Storage Service,简称 OSS),是阿里云提供的海量、安全、低成本、高可靠的云存储服务。您可以在任何应用、任何时间、任何地点存储和访问任意类型的数据。

Alibaba Cloud SchedulerX: 阿里中间件团队开发的一款分布式任务调度产品,提供秒级、精准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务。

Alibaba Cloud SMS: 覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道。


SpringCloudAlibaba Nacos

服务注册和配置中心

前四个字母分别为:Naming 和 Configuration 的前两个字母,最后的 s 为 service

Nacos简介

一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台

Nacos就是注册中心 + 配置中心的组合

Nacos = Eureka + Config + Bus

作用

替代Eureka做服务注册中心

替代Config做服务配置中心

Nacos作为服务注册中心

基于Nacos的服务提供者、基于Nacos的服务消费者

nacos 支持负载均衡,依赖 jar包中包含了Ribbon 轮询负载

@EnableDiscoveryClient

// pom.xml
spring-cloud-starter-alibaba-nacos-discovery

服务注册中心对比

Nacos 和 CAP

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i2WgBVZN-1658223942951)(/Users/wangzeqi/Library/Application Support/typora-user-images/image-20220718104043248.png)]

Nacos支持AP和CP模式切换

C 代表数据一致性,即所有节点在同一时间看到的数据是一致的,数据不一致会直接拒绝响应;

A 代表高可用性,即所有的请求都会收到响应(即使无数据也会收到响应,保持服务是可用状态),但数据可能不一致;

何时选择何种模式?

AP:一般来说,如果不需要存储服务级别的信息,且服务实例都是通过 nacos-client 注册,并期望能够保持心跳上报,那么就要选择AP模式。当前主流的服务,如SpringCloud、Dubbo,都适用于AP模式,AP模式为了服务的高可用性,而会减弱数据的一致性,因此AP模式只支持注册临时实例。

CP:如果需要在服务级别编辑或者存储配置信息,则必须使用CP,k8s服务和DNS服务适用于CP模式。CP模式下支持注册持久化实例,此时是以 Raft 协议为集群运行模式,该模式下注册实例之前必须先注册服务,如果服务不存在,则会返回错误。

执行如下命令可切换集群(根据实际进行修改)

# 切换至CP
curl -X PUT '$NACOS_SERVER:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP'

Nacos作为服务配置中心

Nacos作为基础配置

// pom.xml
spring-cloud-starter-alibaba-nacos-config

@EnableDiscoveryClient

两个配置文件:bootstrap.yml 和 application.yml

Nacos同SpringCloud-config一样,在项目初始化的时候,要保证先从配置中心进行拉取,拉取配置之后,才能保证项目正常启动。

SpringBoot中配置文件的加载顺序是存在优先级的:bootstrap优先级高于application

配置动态更新

// 通过SpringCloud原生注解 @RefreshScope 实现配置自动更新
// 在控制类加入 @RefreshScope注解,使得当前类下的配置支持Nacos配置动态刷新的功能
@RefreshScope

在Nacos中添加配置信息

Nacos中的dataId的组成格式及与SpringBoot配置文件中的匹配原则

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9ILWcO6E-1658223942954)(/Users/wangzeqi/Library/Application Support/typora-user-images/image-20220718113625881.png)]

历史配置回滚

Nacos会记录配置文件中的历史版本默认保留30天,此外还可一键回滚,回滚操作将会触发配置更新。

Nacos作为分类配置

多环境多项目管理:实际开发中,通常分为 dev开发环境、test测试环境、prod生产环境,而一个大型分布式微服务系统会有很多微服务子项目,每个微服务项目又都会有相应的开发环境、测试环境、预发环境、正式环境等,对这些微服务的配置进行管理。

命名空间

NameSpace + Group + DataId 三者关系设计,实现分类配置

类似于Java里面的 包名和类名

最外层的namespace 可以用于区分部署环境,Group 和 DataId 逻辑上区分两个目标对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CHf0Wb3j-1658223942956)(/Users/wangzeqi/Library/Application Support/typora-user-images/image-20220718141030496.png)]

默认情况

Namespace=public,Group=DEFAULT_GROUP, 默认Cluster是DEFAULTNacos默认的命名空间是public,Namespace主要用来实现隔离。比方说我们现在有三个环境:开发、测试、生产环境,我们就可以创建三个Namespace,不同的Namespace之间是隔离的。

Group默认是DEFAULT_GROUP,Group可以把不同的微服务划分到同一个分组里面去。

Service就是微服务;一个Service可以包含多个Cluster(集群),Nacos默认Cluster是DEFAULT,Cluster是对指定微服务的一个虚拟划分。

比方说为了容灾,将Service微服务分别部署在了杭州机房和广州机房,

这时就可以给杭州机房的Service微服务起一个集群名称(HZ),给广州机房的Service微服务起一个集群名称(GZ),还可以尽量让同一个机房的微服务互相调用,以提升性能。

最后是Instance,就是微服务的实例。

CASE

三种方案加载配置:DataId方案、Group方案、NameSpace方案 见脑图

Nacos集群和持久化配置

一直重要的配置是需要保存在Nacos中的,因此为了避免服务宕机数据丢失,需要进行集群部署和持久化配置。

架构图

image-20220718143233389

默认Nacos使用自带的嵌入式数据库(derby)实现数据的存储。即每一个Nacos会自带一个数据库,如果启动多个默认配置下的 Nacos节点,这些Nacos的数据存储在各自内嵌的数据库中,整体的数据存储是存在一致性问题的。(不要各自为战,统一找MySQL)

为了解决这个问题,Nacos采用了集中式存储的方式来支持集群化部署(数据源只有一份,在数据的安全性和一致性方面获得了加强),目前只支持MySQL的存储。

Nacos支持三种部署模式

  • 单机模式-用于测试和单机使用
  • 集群模式-用于生产环境,确保高可用
  • 多集群环境-用于多数据中心场景

单机支持MySQL

单机模式时Nacos使用嵌入式数据库实现数据的存储,不方便观察数据存储的基本情况,因此在0.7版本之后增加了支持MySQL数据源的能力。

Nacos持久化配置

Nacos默认自带的是嵌入式数据库derby

derby 切换至MySQL数据库的步骤(sql脚本和配置文件具体内容见官网):

  1. 在官网找到 sql 脚本,在数据库中执行sql语句,添加相关的数据库表;
  2. nacos的配置文件中,配置MySQL相关信息;
  3. 启动nacos,进入全新的空记录的页面,数据都存储在MySQL中;

Linux版Nacos+MySQL生产环境配置

  1. Nginx + 至少3个Nacos + MySQL

  2. Linux服务器上MySQL数据库配置

  3. 修改配置文件 application.properties

  4. 编辑Linux服务器上的nacos集群配置cluster.conf

    将三台nacos机器的不同服务端口号复制整理至 cluster.conf

​ (注意:这里IP不能写127.0.0.1,必须是 hostname -i命令能识别的IP)

  1. 编辑Nacos的启动脚本 startup.sh,使它能够接收不同的启动端口(脑图)
  2. Nginx的配置,由它作为负载均衡器

Linux 中执行程序

# 在可执行文件前加 ./ 执行  ./代表当前目录
./start.sh

SpringCloudAlibaba Sentinel

简介

Sentinel实现熔断与限流、流量控制

把流量作为切入点,从流量控制、流量路由、熔断降级、系统自适应过载保护、热点流量等多个维度保护服务的稳定性。

特征

  • 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
  • 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
  • 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Apache Dubbo、gRPC、Quarkus 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。同时 Sentinel 提供 Java/Go/C++ 等多语言的原生实现。
  • 完善的 SPI 扩展机制:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。

Sentinel 的主要特性:

image-20220718225605482

Sentinel 的开源生态

image-20220718225708224

Sentinel 分为两个部分

  • 核心库(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。
  • 控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。

服务使用中的各种问题

服务雪崩、服务降级、服务熔断、服务限流

运行sentinel jar包,可直接运行访问,不需要额外的Tomcat等应用容器

# 需要java8及以上环境 and 8080端口不能被占用
java -jar sentinel-dashboard-xxx.jar

关于Sentinel懒加载机制

服务启动后,Sentinel不会加载服务信息,而是采用了懒加载,需要访问一次服务接口,才会显示服务的信息。

流量控制

流量控制flow control),其原理是监控应用流量的 QPS 或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。

流控规则

流量限制控制规则

image-20220719144113178

解释说明

image-20220719145222492
并发线程数控制

并发数控制用于保护业务线程池不被慢调用耗尽。例如,当应用所依赖的下游应用由于某种原因导致服务不稳定、响应延迟增加,对于调用者来说,意味着吞吐量下降和更多的线程数占用,极端情况下甚至导致线程池耗尽。

为应对太多线程占用的情况,业内有使用隔离的方案,比如通过不同业务逻辑使用不同线程池来隔离业务自身之间的资源争抢(线程池隔离)。这种隔离方案虽然隔离性比较好,但是代价就是线程数目太多,线程上下文切换的开销(overhead)比较大,特别是对低延时的调用有较大的影响。

Sentinel并发控制不负责创建和管理线程池,而是简单统计当前请求上下文的线程数目(正在执行的调用数目),如果超出阈值,新的请求会被立即拒绝,效果类似于信号量隔离。并发数控制通常在调用端进行配置

QPS流量控制

当 QPS 超过某个阈值的时候,则采取措施进行流量控制。流量控制的效果包括以下几种:直接拒绝、Warm Up、匀速排队

阈值类型中 QPS和并发线程数的区别
QPS = 并发数/平均响应时间

QPS(TPS):服务每秒响应的请求数 每秒钟 request/事务 数量

并发数:系统同时处理的 请求数/事务数


流控模式
直接

采用 直接 -> 快速失败 的模式(系统默认)

阈值类型配置 QPS 或 线程数

当 api达到限流条件时,直接限流,抛出异常:

Blocked by Sentinel (flow limiting)
关联

当关联的资源达到阈值时,就限流自己

当与A关联的资源B达到阈值后,限流A自己,B惹事,A挂了

作用

在分布式的链路中,各个服务互相调用,相互影响。

比如,商城系统中,支付接口(下游)达到阈值后,就限流下订单的接口(上游),避免连坐效应

下游服务已经到达阈值了,上游服务就需要进行限流处理。下游处理不过来了,上边就别加了。(出入口、入水口)

postman模拟并发密集访问

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nE0Kekze-1658223942963)(/Users/wangzeqi/Library/Application Support/typora-user-images/image-20220719160003707.png)]

链路

只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈值,就进行限流)[api级别的针对来源]

过程略


流控效果

流控效果包括 快速失败、Warm Up、排队等待

快速失败

直接失败,抛出异常 Blocked by Sentinel (flow limiting)

源码:com.alibaba.csp.sentinel.slots.block.flow.controller.DefaultController


Warm Up

Warm Up(RuleConstant.CONTROL_BEHAVIOR_WARM_UP)方式,即预热/冷启动方式。当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sptJUzZB-1658223942965)(/Users/wangzeqi/Library/Application Support/typora-user-images/image-20220719165608738.png)]

根据codeFactor (冷加载因子,默认3)的值,系统初始化的阈值会从设定阈值/codeFactor开始, 经过预热时长,才慢慢恢复到设置的QPS阈值。

应用场景

如:秒杀系统在开启的瞬间,会有很多流量上来,高并发很有可能直接把系统卡死,预热方式就是为了保护系统,可慢慢的把流量放进来,慢慢的把阈值增长到设定的阈值。


匀速排队

匀速排队(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER)方式会严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ogrjbSmd-1658223942967)(/Users/wangzeqi/Library/Application Support/typora-user-images/image-20220719173146529.png)]

应用场景:这种方式主要用于处理间隔性突发的流量,例如消息队列。例如,在某一秒有大量的请求到来,而接下来的几秒则处于空闲状态,我们希望系统能够在接下来的空闲期间逐渐处理这些请求,而不是第一秒直接拒绝多余的请求。

注意:匀速排队模式暂时不支持 QPS > 1000 的场景

漏桶算法 (Leaky Bucket)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q81HnRXd-1658223942972)(/Users/wangzeqi/Library/Application Support/typora-user-images/image-20220719172700079.png)]

// 未完

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值