SpringCloud知识点梳理

1. Spring Cloud 综述

1.1 Spring Cloud 是什么

[百度百科]Spring Cloud是⼀系列框架的有序集合。它利⽤Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中⼼、消息总线、负载均衡、断路器、数据监控等,都可以⽤ Spring Boot的开发⻛格做到⼀键启动和部署。
Spring Cloud并没有重复制造轮⼦,它只是将⽬前各家公司开发的⽐较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot⻛格进⾏再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了⼀套简单易懂、易部署和易维护的分布式系统开发⼯具包。

Spring Cloud是⼀系列框架的有序集合(Spring Cloud是⼀个规范)。
开发服务发现注册、配置中⼼、消息总线、负载均衡、断路器、数据监控等。利⽤Spring Boot的开发便利性简化了微服务架构的开发(⾃动装配)。

这⾥,我们需要注意,Spring Cloud其实是⼀套规范,是⼀套⽤于构建微服务架构的规范,⽽不是⼀个可以拿来即⽤的框架(所谓规范就是应该有哪些功能组件,然后组件之间怎么配合,共同完成什么事情)。在这个规范之下第三⽅的Netflix公司开发了⼀些组件、Spring官⽅开发了⼀些框架/组件,包括第三⽅的阿⾥巴巴开发了⼀套框架/组件集合Spring Cloud Alibaba,这些才是Spring Cloud规范的实现。

Netflix搞了⼀套 简称SCN。

Spring Cloud 吸收了Netflix公司的产品基础之上⾃⼰也搞了⼏个组件。

阿⾥巴巴在之前的基础上搞出了⼀堆微服务组件,Spring Cloud Alibaba(SCA)

1.2 Spring Cloud 解决什么问题

Spring Cloud 规范及实现意图要解决的问题其实就是微服务架构实施过程中存在的⼀些问题,⽐如微服务架构中的服务注册发现问题、⽹络问题(⽐如熔断场景)、统⼀认证安全授权问题、负载均衡问题、链路追踪等问题

1.3 Spring Cloud 架构

如前所述,Spring Cloud是⼀个微服务相关规范,这个规范意图为搭建微服务架构提供⼀站式服务,采⽤组件(框架)化机制定义⼀系列组件,各类组件针对性的处理微服务中的特定问题,这些组件共同来构成Spring Cloud微服务技术栈。

1.3.1 Spring Cloud 核⼼组件

Spring Cloud ⽣态圈中的组件,按照发展可以分为第⼀代 Spring Cloud组件和第⼆代 Spring Cloud组件。

第⼀代 Spring Cloud (Netflix,SCN)第⼆代 Spring Cloud(主要就是Spring Cloud Alibaba,SCA)
注册中⼼Netflix Eureka阿⾥巴巴 Nacos
客户端负载均衡Netflix Ribbon阿⾥巴巴 Dubbo LB、Spring Cloud Loadbalancer
熔断器Netflix Hystrix阿⾥巴巴 Sentinel
⽹关Netflix Zuul:性能⼀般,未来将退出Spring Cloud ⽣态圈官⽅ Spring Cloud Gateway
配置中⼼官⽅ Spring Cloud Config阿⾥巴巴 Nacos、携程 Apollo
服务调⽤Netflix Feign阿⾥巴巴 Dubbo RPC
消息驱动官⽅ Spring Cloud Stream
链路追踪官⽅ Spring Cloud Sleuth/Zipkin
阿⾥巴巴 seata 分布式事务⽅案

spring cloud核心组件

1.3.2 Spring Cloud 体系结构(组件协同⼯作机制)

Spring Cloud 体系结构
Spring Cloud中的各组件协同⼯作,才能够⽀持⼀个完整的微服务架构。⽐如:

  • 注册中⼼负责服务的注册与发现,很好将各服务连接起来。
  • API⽹关负责转发所有外来的请求。
  • 断路器负责监控服务之间的调⽤情况,连续多次失败进⾏熔断保护。
  • 配置中⼼提供了统⼀的配置信息管理服务,可以实时的通知各个服务获取最新的配置信息。

1.4 Spring Cloud 与 Dubbo 对⽐

Dubbo是阿⾥巴巴公司开源的⼀个⾼性能优秀的服务框架,基于RPC调⽤,对于⽬前使⽤率较⾼的Spring Cloud Netflix来说,它是基于HTTP的,所以效率上没有Dubbo⾼,但问题在于Dubbo体系的组件不全,不能够提供⼀站式解决⽅案,⽐如服务注册与发现需要借助于Zookeeper等实现,⽽Spring Cloud Netflix则是真正的提供了⼀站式服务化解决⽅案,且有Spring⼤家族背景。

前些年,Dubbo使⽤率⾼于SpringCloud,但⽬前Spring Cloud在服务化/微服务解决⽅案中已经有了⾮常好的发展趋势。

1.5 Spring Cloud 与 Spring Boot 的关系

Spring Cloud 只是利⽤了Spring Boot 的特点,让我们能够快速的实现微服务组件开发,否则不使⽤Spring Boot的话,我们在使⽤Spring Cloud时,每⼀个组件的相关Jar包都需要我们⾃⼰导⼊配置以及需要开发⼈员考虑兼容性等各种情况。所以Spring Boot是我们快速把Spring Cloud微服务技术应⽤起来的⼀种⽅式。

2. 第⼀代 Spring Cloud 核⼼组件详解

由于⽹关组件Zuul性能⼀般,未来将退出Spring Cloud ⽣态圈,所以我们直接讲解GateWay,我们把GateWay划分到第⼀代Spring Cloud 核⼼组件这⼀部分了。

各组件整体结构如下:
第⼀代 Spring Cloud 核⼼组件
从形式上来说,Feign⼀个顶三,Feign = RestTemplate + Ribbon + Hystrix

2.1 Eureka服务注册中⼼

2.1.1 关于服务注册中⼼

注意:服务注册中⼼本质上是为了解耦服务提供者和服务消费者。

对于任何⼀个微服务,原则上都应存在或者⽀持多个提供者(⽐如简历微服务部署多个实例),这是由微服务的分布式属性决定的。

更进⼀步,为了⽀持弹性扩缩容特性,⼀个微服务的提供者的数量和分布往往是动态变化的,也是⽆法预先确定的。因此,原本在单体应⽤阶段常⽤的静态LB机制就不再适⽤了,需要引⼊额外的组件来管理微服务提供者的注册与发现,⽽这个组件就是服务注册中⼼。

  1. 服务注册中⼼⼀般原理
    分布式微服务架构中,服务注册中⼼⽤于存储服务提供者地址信息、服务发布相关的属性信息,消费者通过主动查询和被动通知的⽅式获取服务提供者的地址信息,⽽不再需要通过硬编码⽅式得到提供者的地址信息。消费者只需要知道当前系统发布了那些服务,⽽不需要知道服务具体存在于什么位置,这就是透明化路由。

    在这里插入图片描述

    1. 服务提供者启动
    2. 服务提供者将相关服务信息主动注册到注册中⼼
    3. 服务消费者获取服务注册信息:
      pull模式:服务消费者可以主动拉取可⽤的服务提供者清单;
      push模式:服务消费者订阅服务(当服务提供者有变化时,注册中⼼也会主动推送更新后的服务清单给消费者。
    4. 服务消费者直接调⽤服务提供者。


    另外,注册中⼼也需要完成服务提供者的健康监控,当发现服务提供者失效时需要及时剔除。

  2. 主流服务中⼼对⽐

    • Zookeeper
      Zookeeper它是⼀个分布式服务框架,是Apache Hadoop 的⼀个⼦项⽬,它主要是⽤来解决分布式应 ⽤中经常遇到的⼀些数据管理问题,如:统⼀命名服务、状态同步服务、集群管理、分布式应⽤配置项的管理等。
      简单来说zookeeper本质=存储+监听通知。

      znode节点
      Zookeeper ⽤来做服务注册中⼼,主要是因为它具有节点变更通知功能,只要客户端监听相关服务节点,服务节点的所有变更,都能及时的通知到监听客户端,这样作为调⽤⽅只要使⽤ Zookeeper 的客户端就能实现服务节点的订阅和变更通知功能了,⾮常⽅便。另外,Zookeeper 可⽤性也可以,因为只要半数以上的选举节点存活,整个集群就是可⽤的。(集群最少3台)
    • Eureka
      由Netflix开源,并被Pivatal集成到SpringCloud体系中,它是基于 RestfulAPI⻛格开发的服务注册与发现组件。
    • Consul
      Consul是由HashiCorp基于Go语⾔开发的⽀持多数据中⼼分布式⾼可⽤的服务发布和注册服务软件, 采⽤Raft算法保证服务的⼀致性,且⽀持健康检查。
    • Nacos
      Nacos是⼀个更易于构建云原⽣应⽤的动态服务发现、配置管理和服务管理平台。简单来说 Nacos 就是 注册中⼼ + 配置中⼼的组合,帮助我们解决微服务开发必会涉及到的服务注册 与发现,服务配置,服务管理等问题。
      Nacos 是Spring Cloud Alibaba 核⼼组件之⼀,负责服务注册与发现,还有配置。
    组件名语⾔CAP对外暴露接⼝
    EurekaJavaAP(⾃我保护机制,保证可⽤)HTTP
    ConsulGoCPHTTP/DNS
    ZookeeperJavaCP客户端
    NacosJava⽀持AP/CP切换HTTP

    P:分区容错性(⼀定的要满⾜的)
    C:数据⼀致性
    A:⾼可⽤
    CAP不可能同时满⾜三个,要么是AP,要么是CP

2.1.2 服务注册中⼼组件 Eureka

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

    Eureka 交互流程及原理

    1. 图中us-east-1c、us-east-1d,us-east-1e代表不同的区也就是不同的机房;
    2. 图中每⼀个Eureka Server都是⼀个集群;
    3. 图中Application Service作为服务提供者向Eureka Server中注册服务,Eureka Server接受到注册事件会在集群和分区中进⾏数据同步,Application Client作为消费端(服务消费者)可以从Eureka Server中获取到服务注册信息,进⾏服务调⽤;
    4. 微服务启动后,会周期性地向Eureka Server发送⼼跳(默认周期为30秒)以续约⾃⼰的信息;
    5. Eureka Server在⼀定时间内没有接收到某个微服务节点的⼼跳,Eureka Server将会注销该微服务节点(默认90秒);
    6. 每个Eureka Server同时也是Eureka Client,多个Eureka Server之间通过复制的⽅式完成服务注册列表的同步;
    7. Eureka Client会缓存Eureka Server中的信息。即使所有的Eureka Server节点都宕掉,服务消费者依然可以使⽤缓存中的信息找到服务提供者。


    Eureka通过⼼跳检测、健康检查和客户端缓存等机制,提⾼系统的灵活性、可伸缩性和可⽤性。

2.1.3 Eureka应⽤及⾼可⽤集群

1)单实例Eureka Server—>访问管理界⾯—>Eureka Server集群
2)服务提供者(简历微服务注册到集群)
3)服务消费者(⾃动投递微服务注册到集群/从Eureka Server集群获取服务信息)
4)完成调⽤

2.1.4 Eureka细节详解

  1. Eureka元数据详解
    Eureka的元数据有两种:标准元数据⾃定义元数据
    标准元数据:主机名、IP地址、端⼝号等信息,这些信息都会被发布在服务注册表中,⽤于服务之间的调⽤。
    ⾃定义元数据:可以使⽤eureka.instance.metadata-map配置,符合KEY/VALUE的存储格式。这 些元数据可以在远程客户端中访问。

    类似于:

    instance:prefer-ip-address: truemetadata-map:# ⾃定义元数据(kv⾃定义)cluster: cl1region: rn1
    
  2. Eureka客户端详解
    服务提供者(也是Eureka客户端)要向EurekaServer注册服务,并完成服务续约等⼯作。

    服务注册详解(服务提供者)

    1. 当我们导⼊了eureka-client依赖坐标,配置Eureka服务注册中⼼地址
    2. 服务在启动时会向注册中⼼发起注册请求,携带服务元数据信息
    3. Eureka注册中⼼会把服务的信息保存在Map中。

    服务续约详解(服务提供者)
    服务每隔30秒会向注册中⼼续约(⼼跳)⼀次(也称为报活),如果没有续约,租约在90秒后到期,然后服务会被失效。
    每隔30秒的续约操作我们称之为⼼跳检测。

    往往不需要我们调整这两个配置:

    #向Eureka服务中⼼集群注册服务
    eureka:instance:# 租约续约间隔时间,默认30秒lease-renewal-interval-in-seconds: 30# 租约到期,服务时效时间,默认值90,服务超过90秒没有发⽣⼼跳,EurekaServer会将服务从列表移除lease-expiration-duration-in-seconds: 90
    

    获取服务列表详解(服务消费者)
    每隔30秒服务会从注册中⼼中拉取⼀份服务列表,这个时间可以通过配置修改。往往不需要我们调整

    #向Eureka服务中⼼集群注册服务
    eureka:client:# 每隔多久拉取⼀次服务列表registry-fetch-interval-seconds: 30
    
    1. 服务消费者启动时,从 EurekaServer服务列表获取只读备份,缓存到本地
    2. 每隔30秒,会重新获取并更新数据
    3. 每隔30秒的时间可以通过配置eureka.client.registry-fetch-interval-seconds修改
  3. Eureka服务端详解

    服务下线

    1. 当服务正常关闭操作时,会发送服务下线的REST请求给EurekaServer。
    2. 服务中⼼接受到请求后,将该服务置为下线状态。

    失效剔除
    Eureka Server会定时(间隔值是eureka.server.eviction-interval-timer-in-ms,默认60s)进⾏检查,如果发现实例在在⼀定时间(此值由客户端设置的eureka.instance.lease-expiration-duration-in-seconds定义,默认值为90s)内没有收到⼼跳,则会注销此实例。

    ⾃我保护
    服务提供者 —> 注册中⼼
    定期的续约(服务提供者和注册中⼼通信),假如服务提供者和注册中⼼之间的⽹络有点问题,不代表服务提供者不可⽤,不代表服务消费者⽆法访问服务提供者。如果在15分钟内超过85%的客户端节点都没有正常的⼼跳,那么Eureka就认为客户端与注册中⼼出现了⽹络故障,Eureka Server⾃动进⼊⾃我保护机制。


    为什么会有⾃我保护机制?
    默认情况下,如果Eureka Server在⼀定时间内(默认90秒)没有接收到某个微服务实例的⼼跳,Eureka Server将会移除该实例。但是当⽹络分区故障发⽣时,微服务与Eureka Server之间⽆法正常通信,⽽微服务本身是正常运⾏的,此时不应该移除这个微服务,所以引⼊了⾃我保护机制。


    服务中⼼⻚⾯会显示如下提示信息:
    自我保护机制


    当处于⾃我保护模式时:

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

    经验:建议⽣产环境打开⾃我保护机制

2.2 Ribbon负载均衡

2.2.1 关于负载均衡

负载均衡⼀般分为服务器端负载均衡客户端负载均衡

所谓服务器端负载均衡,⽐如Nginx、F5这些,请求到达服务器之后由这些负载均衡器根据⼀定的算法将请求路由到⽬标服务器处理。

所谓客户端负载均衡,⽐如我们要说的Ribbon,服务消费者客户端会有⼀个服务器地址列表,调⽤⽅在请求前通过⼀定的负载均衡算法选择⼀个服务器进⾏访问,负载均衡算法的执⾏是在请求客户端进⾏。

Ribbon是Netflix发布的负载均衡器。Eureka⼀般配合Ribbon进⾏使⽤,Ribbon利⽤从Eureka中读取到服务信息,在调⽤服务提供者提供的服务时,会根据⼀定的算法进⾏负载。
Ribbon负载均衡

2.2.2 Ribbon⾼级应⽤

不需要引⼊额外的Jar坐标,因为在服务消费者中我们引⼊过eureka-client,它会引⼊Ribbon相关Jar。

代码中使⽤如下,在RestTemplate上添加对应注解即可:

@Bean
// Ribbon负载均衡
@LoadBalanced
public RestTemplate getRestTemplate() {return new RestTemplate();
} 

2.2.3 Ribbon负载均衡策略

Ribbon内置了多种负载均衡策略,内部负责负载均衡的顶级接⼝为com.netflix.loadbalancer.IRule ,类树如下:
Ribbon负载均衡类

负载均衡策略描述
RoundRobinRule:轮询策略默认超过10次获取到的server都不可⽤,会返回⼀个空的server
RandomRule:随机策略如果随机到的server为null或者不可⽤的话,会while不停的循环选取
RetryRule:重试策略⼀定时限内循环重试。默认继承RoundRobinRule,也⽀持⾃定义注⼊,RetryRule会在每次选取之后,对选举的server进⾏判断,是否为null,是否alive,并且在500ms内会不停的选取判断。⽽RoundRobinRule失效的策略是超过10次,RandomRule是没有失效时间的概念,只要serverList没都挂。
BestAvailableRule:最⼩连接数策略遍历serverList,选取出可⽤的且连接数最⼩的⼀个server。该算法⾥⾯有⼀个LoadBalancerStats的成员变量,会存储所有server的运⾏状况和连接数。如果选取到的server为null,那么会调⽤RoundRobinRule重新选取。1(1) 2(1)3(1)
AvailabilityFilteringRule:可⽤过滤策略扩展了轮询策略,会先通过默认的轮询选取⼀个server,再去判断该server是否超时可⽤,当前连接数是否超限,都成功再返回。
ZoneAvoidanceRule:区域权衡策略(默认策略扩展了轮询策略,继承了2个过滤器:ZoneAvoidancePredicate和AvailabilityPredicate,除了过滤超时和链接数过多的server,还会过滤掉不符合要求的zone区域⾥⾯的所有节点,AWS --ZONE 在⼀个区域/机房内的服务实例中轮询

修改负载均衡策略:

# 针对的被调⽤⽅微服务名称,不加就是全局⽣效
work-service-resume:ribbon:NFLoadBalancerRuleClassName:com.netflix.loadbalancer.RandomRule #负载策略调整

2.2.4 Ribbon核⼼原理剖析

Ribbon⼯作原理:
Ribbon工作原理
重点:Ribbon给restTemplate添加了⼀个拦截器

思考:Ribbon在做什么:
当我们访问http://work-service-resume/resume/openstate/的时候,ribbon应该根据服务名work-service-resume获取到该服务的实例列表并按照⼀定的负载均衡策略从实例列表中获取⼀个实例Server,并最终通过RestTemplate进⾏请求访问。

Ribbon细节结构图(涉及到底层的⼀些组件/类的描述):
1)获取服务实例列表
2)从列表中选择⼀个server

Ribbon核心结构图
图中核⼼是负载均衡管理器LoadBalancer(总的协调者,相当于⼤脑,为了做事情,协调四肢),围绕它周围的多有IRule、IPing等。

  • IRule:是在选择实例的时候的负载均衡策略对象;
  • IPing:是⽤来向服务发起⼼跳检测的,通过⼼跳检测来判断该服务是否可⽤;
  • ServerListFilter:根据⼀些规则过滤传⼊的服务实例列表;
  • ServerListUpdater:定义了⼀系列的对服务列表的更新操作。

2.3 Hystrix熔断器

属于⼀种容错机制。

2.3.1 微服务中的雪崩效应

什么是微服务中的雪崩效应呢?
微服务中,⼀个请求可能需要多个微服务接⼝才能实现,会形成复杂的调⽤链路。

雪崩效应

扇⼊:代表着该微服务被调⽤的次数,扇⼊⼤,说明该模块复⽤性好
扇出:该微服务调⽤其他微服务的个数,扇出⼤,说明业务逻辑复杂

扇⼊⼤是⼀个好事,扇出⼤不⼀定是好事

在微服务架构中,⼀个应⽤可能会有多个微服务组成,微服务之间的数据交互通过远程过程调⽤完成。这就带来⼀个问题,假设微服务A调⽤微服务B和微服务C,微服务B和微服务C⼜调⽤其它的微服务,这就是所谓的“扇出”。如果扇出的链路上某个微服务的调⽤响应时间过⻓或者不可⽤,对微服务A的调⽤就会占⽤越来越多的系统资源,进⽽引起系统崩溃,所谓的“雪崩效应”。

如图中所示,最下游简历微服务响应时间过⻓,⼤量请求阻塞,⼤量线程不会释放,会导致服务器资源耗尽,最终导致上游服务甚⾄整个系统瘫痪。

2.3.2 雪崩效应解决⽅案

从可⽤性可靠性着想,为防⽌系统的整体缓慢甚⾄崩溃,采⽤的技术⼿段;

下⾯,我们介绍三种技术⼿段应对微服务中的雪崩效应,这三种⼿段都是从系统可⽤性、可靠性⻆度出发,尽量防⽌系统整体缓慢甚⾄瘫痪。

  1. 服务熔断
    熔断机制是应对雪崩效应的⼀种微服务链路保护机制。
    我们在各种场景下都会接触到熔断这两个字。⾼压电路中,如果某个地⽅的电压过⾼,熔断器就会熔断,对电路进⾏保护。股票交易中,如果股票指数过⾼,也会采⽤熔断机制,暂停股票的交易。
    同样,在微服务架构中,熔断机制也是起着类似的作⽤。当扇出链路的某个微服务不可⽤或者响应时间太⻓时,熔断该节点微服务的调⽤,进⾏服务的降级,快速返回错误的响应信息。当检测到该节点微服务调⽤响应正常后,恢复调⽤链路。

    注意
    1)服务熔断重点在“断”,切断对下游服务的调⽤。
    2)服务熔断和服务降级往往是⼀起使⽤的,Hystrix就是这样。

  2. 服务降级
    通俗讲就是整体资源不够⽤了,先将⼀些不关紧的服务停掉(调⽤我的时候,给你返回⼀个预留的值,也叫做兜底数据),待渡过难关⾼峰过去,再把那些服务打开。

    服务降级⼀般是从整体考虑,就是当某个服务熔断之后,服务器将不再被调⽤,此刻客户端可以⾃⼰准备⼀个本地的fallback回调,返回⼀个缺省值,这样做,虽然服务⽔平下降,但好⽍可⽤,⽐直接挂掉要强。

  3. 服务限流
    服务降级是当服务出问题或者影响到核⼼流程的性能时,暂时将服务屏蔽掉,待⾼峰或者问题解决后再打开;但是有些场景并不能⽤服务降级来解决,⽐如秒杀业务这样的核⼼功能,这个时候可以结合服务限流来限制这些场景的并发/请求量。

    限流措施也很多,⽐如:

    • 限制总并发数(⽐如数据库连接池、线程池)
    • 限制瞬时并发数(如nginx限制瞬时并发连接数)
    • 限制时间窗⼝内的平均速率(如Guava的RateLimiter、nginx的limit_req模块,限制每秒的平均速率)
    • 限制远程接⼝调⽤速率、限制MQ的消费速率等

2.3.3 Hystrix简介

[来⾃官⽹]Hystrix(豪猪----->刺),宣⾔“defend your app”是由Netflix开源的⼀个延迟和容错库,⽤于隔离访问远程系统、服务或者第三⽅库,防⽌级联失败,从⽽提升系统的可⽤性与容错性。

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

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

2.3.4 Hystrix熔断应⽤

⽬的:简历微服务⻓时间没有响应,服务消费者—>⾃动投递微服务快速失败给⽤户提示。
服务熔断
只需要在服务调用端添加熔断策略,服务提供方不需要做任何修改。

  1. 服务消费者⼯程(⾃动投递微服务)中引⼊Hystrix依赖坐标(也可以添加在⽗⼯程中)
  2. 服务消费者⼯程(⾃动投递微服务)的启动类中添加熔断器开启注解@EnableCircuitBreaker
  3. 定义服务降级处理⽅法,并在业务⽅法上使⽤@HystrixCommand的fallbackMethod属性关联到服务降级处理⽅法。
    注意:
    降级(兜底)⽅法必须和被降级⽅法相同的⽅法签名(相同参数列表、相同返回值)
  4. 可以在类上使⽤@DefaultProperties注解统⼀指定整个类中共⽤的降级(兜底)⽅法

2.3.5 Hystrix舱壁模式(线程池隔离策略)

问题:
Hystrix问题
如果不进⾏任何设置,所有熔断⽅法使⽤⼀个Hystrix线程池(10个线程),那么这样的话会导致问题,这个问题并不是扇出链路微服务不可⽤导致的,⽽是我们的线程机制导致的,如果⽅法A的请求把10个线程都⽤了,⽅法2请求处理的时候压根都没法去访问B,因为没有线程可⽤,并不是B服务不可⽤。

Hystrix舱壁模式
为了避免问题服务请求过多导致正常服务⽆法访问,Hystrix不是采⽤增加线程数,⽽是单独的为每⼀个控制⽅法创建⼀个线程池的⽅式,这种模式叫做"舱壁模式",也是线程隔离的⼿段。

2.3.6 Hystrix⼯作流程与⾼级应⽤

Hystrix⼯作流

  1. 当调⽤出现问题时,开启⼀个时间窗(10s)
  2. 在这个时间窗内,统计调⽤次数是否达到最⼩请求数?
    如果没有达到,则重置统计信息,回到第1步。
    如果达到了,则统计失败的请求数占所有请求数的百分⽐,是否达到阈值?
    如果达到,则跳闸(不再请求对应服务)。
    如果没有达到,则重置统计信息,回到第1步。
  3. 如果跳闸,则会开启⼀个活动窗⼝(默认5s),每隔5s,Hystrix会让⼀个请求通过,到达那个问题服务,看 是否调⽤成功,如果成功,重置断路器回到第1步,如果失败,回到第3步。
  1. 跳闸逻辑设置

    /*** 8秒钟内,请求次数达到2个,并且失败率在50%以上,就跳闸* 跳闸后活动窗⼝设置为3s*/@HystrixCommand(commandProperties = {@HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds",value = "8000"),@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "2"),@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "50"),@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "3000")})
    
  2. 我们上述通过注解进⾏的配置也可以配置在配置⽂件中:

    # 配置熔断策略:
    hystrix:command:default:circuitBreaker:# 强制打开熔断器,如果该属性设置为true,强制断路器进⼊打开状态,将会拒绝所有的请求。 默认false关闭的forceOpen: false# 触发熔断错误⽐例阈值,默认值50%errorThresholdPercentage: 50# 熔断后休眠时⻓,默认值5秒sleepWindowInMilliseconds: 3000# 熔断触发最⼩请求次数,默认值是20requestVolumeThreshold: 2execution:isolation:thread:# 熔断超时设置,默认为1秒timeoutInMilliseconds: 2000
    
  3. 基于springboot的健康检查观察跳闸状态(⾃动投递微服务暴露健康检查细节)

    # springboot中暴露健康检查等断点接⼝
    management:endpoints:web:exposure:include: "*"# 暴露健康接⼝的细节endpoint:health:show-details: always
    

    访问健康检查接⼝:http://localhost:8090/actuator/health

    hystrix正常⼯作状态:

    在这里插入图片描述

    跳闸状态:
    跳闸状态

    活动窗⼝内⾃我修复:
    自我修复

2.3.7 Hystrix Dashboard断路监控仪表盘

正常状态是UP,跳闸是⼀种状态CIRCUIT_OPEN,可以通过/health查看,前提是⼯程中需要引⼊SpringBoot的actuator(健康监控),它提供了很多监控所需的接⼝,可以对应⽤系统进⾏配置查看、相关功能统计等。

已经统⼀添加在⽗⼯程中:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

如果我们想看到Hystrix相关数据,⽐如有多少请求、多少成功、多少失败、多少降级等,那么引⼊SpringBoot健康监控之后,访问/actuator/hystrix.stream接⼝可以获取到监控的⽂字信息,但是不直观,所以Hystrix官⽅还提供了基于图形化的DashBoard(仪表板)监控平 台。Hystrix仪表板可以显示每个断路器(被@HystrixCommand注解的⽅法)的状态。
Hystrix监控监控

  1. 新建⼀个监控服务⼯程,导⼊依赖

    <!--hystrix 仪表盘-->
    <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrixdashboard</artifactId>
    </dependency>
    
  2. 启动类添加@EnableHystrixDashboard激活仪表盘

    @SpringBootApplication
    @EnableHystrixDashboard // 开启hystrix dashboard
    public class HystrixDashboardApplication9000 {public static void main(String[] args) {SpringApplication.run(HystrixDashboardApplication.class, args);}
    } 
    
  3. 配置 application.yml

    server:port: 9000
    Spring:application:name: lagou-cloud-hystrix-dashboard
    eureka:client:serviceUrl: # eureka server的路径defaultZone:http://lagoucloudeurekaservera:8761/eureka/,http://lagoucloudeurekaserverb:8762/eureka/ #把 eureka 集群中的所有 url 都填写了进来,也可以只写⼀台,因为各个 eureka server 可以同步注册表instance:#使⽤ip注册,否则会使⽤主机名注册了(此处考虑到对⽼版本的兼容,新版本经过实验都是ip)prefer-ip-address: true#⾃定义实例显示格式,加上版本号,便于多版本管理,注意是ip-address,早期版本是ipAddressinstance-id: ${spring.cloud.client.ipaddress}:${spring.application.name}:${server.port}:@project.version@
    
  4. 在被监测的微服务中注册监控servlet(⾃动投递微服务,监控数据就是来⾃于这个微服务)

    @Bean
    public ServletRegistrationBean getServlet(){HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);registrationBean.setLoadOnStartup(1);registrationBean.addUrlMappings("/actuator/hystrix.stream");registrationBean.setName("HystrixMetricsStreamServlet");return registrationBean;
    }
    

    被监控微服务发布之后,可以直接访问监控servlet,但是得到的数据并不直观,后期可以结合仪表盘更友好的展示。
    在这里插入图片描述

  5. 访问测试http://localhost:9000/hystrix
    Hystrix仪表盘
    输入监控的微服务端点地址,展示监控的详细数据,比如监控服务消费者http://locahost:8090/actuator/hystrix.stream

    在这里插入图片描述

    百分⽐:

    • 10s内错误请求百分⽐

    实⼼圆:

    • ⼤⼩:代表请求流量的⼤⼩,流量越⼤球越⼤
    • 颜⾊:代表请求处理的健康状态,从绿⾊到红⾊递减,绿⾊代表健康,红⾊就代表很不健康

    曲线波动图:

    • 记录了2分钟内该⽅法上流量的变化波动图,判断流量上升或者下降的趋势

2.4 Feign远程调⽤组件

服务消费者调⽤服务提供者的时候使⽤RestTemplate技术:
RestTemplate远程调用
存在不便之处
1)拼接url
2)restTmplate.getForObJect
这两处代码都⽐较模板化,能不能不让我们来写这种模板化的东⻄?
另外来说,拼接url⾮常的low,拼接字符串,拼接参数,很low还容易出错。

2.4.1 Feign简介

Feign是Netflix开发的⼀个轻量级RESTful的HTTP服务客户端(⽤它来发起请求,远程调⽤的),是以Java接⼝注解的⽅式调⽤Http请求,⽽不⽤像Java中通过封装HTTP请求报⽂的⽅式直接调⽤,Feign被⼴泛应⽤在Spring Cloud 的解决⽅案中。

类似于Dubbo,服务消费者拿到服务提供者的接⼝,然后像调⽤本地接⼝⽅法⼀样去调⽤,实际发出的是远程的请求。

  • Feign可帮助我们更加便捷,优雅的调⽤HTTP API:不需要我们去拼接url,然后调⽤restTemplate的api。在SpringCloud中,使⽤Feign⾮常简单,创建⼀个接⼝(在消费者–服务调⽤⽅这⼀端),并在接⼝上添加⼀些注解,代码就完成了
  • SpringCloud对Feign进⾏了增强,使Feign⽀持了SpringMVC注解(OpenFeign)

本质:封装了Http调⽤流程,更符合⾯向接⼝化的编程习惯,类似于Dubbo的服务调⽤。
Dubbo的调⽤⽅式其实就是很好的⾯向接⼝编程。

2.4.2 Feign配置应⽤

服务调⽤者⼯程(消费)创建接⼝(添加注解)
(效果)Feign = RestTemplate+Ribbon+Hystrix

  1. 服务消费者⼯程(⾃动投递微服务)中引⼊Feign依赖(或者⽗类⼯程)。

    <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    
  2. 服务消费者⼯程(⾃动投递微服务)启动类使⽤注解@EnableFeignClients添加Feign⽀持。

    @SpringBootApplication
    @EnableDiscoveryClient // 开启服务发现
    @EnableFeignClients // 开启Feign
    public class AutodeliverFeignApplication8092 {public static void main(String[] args) {SpringApplication.run(AutodeliverFeignApplication8092.class,args);}
    }
    

    注意:此时去掉Hystrix熔断的⽀持注解@EnableCircuitBreaker即可包括引⼊的依赖,因为Feign会⾃动引⼊。

  3. 创建Feign接⼝。

    // name:调⽤的服务名称,和服务提供者yml⽂件中spring.application.name保持⼀致
    @FeignClient(name="work-service-resume")
    public interface ResumeFeignClient {//调⽤的请求路径@RequestMapping(value = "/resume/openstate/{userId}", method=RequestMethod.GET)public Integer findResumeOpenState(@PathVariable(value ="userId") Long userId);}
    

    注意:

    • 1)@FeignClient注解的name属性⽤于指定要调⽤的服务提供者名称,和服务提供者yml⽂件中spring.application.name保持⼀致。
    • 2)接⼝中的接⼝⽅法,就好⽐是远程服务提供者Controller中的Hander⽅法(只不过如同本地调⽤了),那么在进⾏参数绑定的时,可以使⽤@PathVariable、@RequestParam、@RequestHeader等,这也是OpenFeign对SpringMVC注解的⽀持,但是需要注意value必须设置,否则会抛出异常。
  4. 使⽤接⼝中⽅法完成远程调⽤(注⼊接⼝即可,实际注⼊的是接⼝的实现)。

    @Autowired
    private ResumeFeignClient resumeFeignClient;
    @Test
    public void testFeignClient(){Integer resumeOpenState = resumeFeignClient.findResumeOpenState(1545132l);System.out.println("=======>>>resumeOpenState:" + resumeOpenState);
    }
    

2.4.3 Feign对负载均衡的⽀持

Feign 本身已经集成了Ribbon依赖和⾃动配置,因此我们不需要额外引⼊依赖,可以通过 ribbon.xx 来进⾏全局配置,也可以通过服务名.ribbon.xx 来对指定服务进⾏细节配置配置(参考之前,此处略)。

Feign默认的请求处理超时时⻓1s,有时候我们的业务确实执⾏的需要⼀定时间,那么这个时候,我们就需要调整请求处理超时时⻓,Feign⾃⼰有超时设置,如果配置Ribbon的超时,则会以Ribbon的为准。

Ribbon设置:

#针对的被调⽤⽅微服务名称,不加就是全局⽣效
lagou-service-resume:ribbon:#请求连接超时时间#ConnectTimeout: 2000#请求处理超时时间#ReadTimeout: 5000#对所有操作都进⾏重试OkToRetryOnAllOperations: true####根据如上配置,当访问到故障请求的时候,它会再尝试访问⼀次当前实例(次数由MaxAutoRetries配置),####如果不⾏,就换⼀个实例进⾏访问,如果还不⾏,再换⼀次实例访问(更换次数由MaxAutoRetriesNextServer配置),####如果依然不⾏,返回失败信息。MaxAutoRetries: 0 #对当前选中实例重试次数,不包括第⼀次调⽤MaxAutoRetriesNextServer: 0 #切换实例的重试次数NFLoadBalancerRuleClassName:com.netflix.loadbalancer.RoundRobinRule #负载策略调整

2.4.4 Feign对熔断器的⽀持

  1. 在Feign客户端⼯程配置⽂件(application.yml)中开启Feign对熔断器的⽀持

    # 开启Feign的熔断功能
    feign:hystrix:enabled: true
    

    Feign的超时时⻓设置那其实就上⾯Ribbon的超时时⻓设置
    Hystrix超时设置(就按照之前Hystrix设置的⽅式就OK了)

    注意:

    • 1)开启Hystrix之后,Feign中的⽅法都会被进⾏⼀个管理了,⼀旦出现问题就进⼊对应的回退逻辑处理。

    • 2)针对超时这⼀点,当前有两个超时时间设置(Feign/hystrix),熔断的时候是根据这两个时间的最⼩值来进⾏的,即处理时⻓超过最短的那个超时时间了就熔断进⼊回退降级逻辑。

      hystrix:command:default:execution:isolation:thread:######### Hystrix的超时时⻓设置timeoutInMilliseconds: 15000
      
  2. ⾃定义FallBack处理类(需要实现FeignClient接⼝)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/5850.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(C语言)文件操作与函数,超详解

目录 1. 文件 1.1 为什么使用文件&#xff1f; 1.2 什么是文件&#xff1f; 1.2.1 程序文件 1.2.2 数据文件 1.3 文件名 1.4 二进制文件和文本文件 2. 文件的打开和关闭 2.1 流和标准流 2.1.1 流 2.1.2 标准流 2.2 文件指针 2.3 文件的打开和关闭 3. 文件的顺序…

Go Web 开发【Gin 框架快速开发】

1、Gin Web 快速开发 1.1、环境准备 1.1.1、导入 gin 依赖 这里就叫 gin 依赖了&#xff0c;在 Goland 命令行中输入下面的命令&#xff1a; go get -u github.com/gin-gonic/gin 1.1.2、设置代理 如果下载失败&#xff0c;最好设置一下代理&#xff0c;在 cmd 命令行中输…

深度学习论文:Local Feature Matching Using Deep Learning: A Survey

深度学习论文: Local Feature Matching Using Deep Learning: A Survey Local Feature Matching Using Deep Learning: A Survey PDF: https://arxiv.org/pdf/2401.17592 1 概述 近年来&#xff0c;深度学习模型的引入引发了对局部特征匹配技术的广泛探索。本文旨在全面概述局…

爬虫学习:基本网络请求库的使用

目录 一、urllib网络库 1.urlopen()方法 2.request方法 二、requests网络请求库 1.主要方法 2.requests.get()和requests.post() 一、urllib网络库 1.urlopen()方法 语法格式&#xff1a; urlopen(url,data,timeout,cafile,capath,context) # url:地址 # data:要提交的数据…

POWERBI==官网教程

地址 COVID-19 tracking sample for US state and local governments - Power BI | Microsoft Learn 已经非常全面了

JSON教程(非常详细)

参考文章来源&#xff1a;JSON教程&#xff08;非常详细&#xff09; 目录 JSON JSON 发展史 为什么要使用 JSON&#xff1f; JSON 的不足 存储格式 使用场景 1) 定义接口 2) 序列化 3) 生成 Token 4) 配置文件 JSON语法规则 JSON 与 JavaScript 对象的区别 JSON数…

解决Pycharm全局搜索与输入法简繁切换快捷键冲突问题

Pycharm中全局搜索快捷键Ctrl Shift F 如图所示&#xff1a; 微软输入法简繁切换快捷键设置&#xff1a; 解决办法&#xff1a; 关掉输入法的切换功能即可&#xff0c;或者更改简繁切换快捷键&#xff0c;毕竟简繁切换使用频率极低。

骑缝电子章怎么盖?

盖骑缝电子章通常涉及几个基本步骤&#xff0c;这里提供一个通用的流程&#xff0c;适用于大多数电子文档处理软件&#xff0c;尤其是那些支持电子签名和印章功能的软件&#xff0c;比如Adobe Acrobat Pro DC、e-章宝(易友EU3000智能盖章软件)等。请注意&#xff0c;具体操作可…

2024年五一数学建模C题完整解题思路代码

2024年第二十一届五一数学建模竞赛题目 C题 煤矿深部开采冲击地压危险预测 煤炭是中国的主要能源和重要的工业原料。然而&#xff0c;随着开采深度的增加&#xff0c;地应力增大&#xff0c;井下煤岩动力灾害风险越来越大&#xff0c;严重影响着煤矿的安全高效开采。在各类深…

路由器的构成

一、路由器简介 路由器是互联网中的关键设备&#xff1a; 连接不同的网络路由器是多个输入端口和多个输出端口的专用计算机&#xff0c;其任务是转发分组&#xff08;转发给下一跳路由器&#xff09;下一跳路由器也按照这种方法处理分组&#xff0c;直到该分组到达终点为止 …

Pandas入门篇(二)-------Dataframe篇4(进阶)(Dataframe的进阶用法)(机器学习前置技术栈)

目录 概述一、复合索引&#xff08;一&#xff09;创建具有复合索引的 DataFrame1. 使用 set_index 方法&#xff1a;2.在创建 DataFrame 时直接指定索引&#xff1a; &#xff08;二&#xff09;使用复合索引进行数据选择和切片&#xff08;三&#xff09;重置索引&#xff08…

使用 Langchain、Langfuse、Nemo-gaurdrails、RAGAs构建 RAG 管道并进行监控和评估

原文地址:build-end-to-end-rag-pipeline-with-monitoring-and-evaluation-using-langchain-azure-ai-search 2024 年 4 月 21 日 介绍 使用现代的LLM框架,如Langchain或llamaindex,可以迅速搭建一个用于 RAG 的管道,通常只需编写大约5-6行代码。然而,若要构建一个适用于生…

【小浩算法 BST与其验证】

BST与其验证 前言我的思路思路一 中序遍历判断数组无重复递增思路二 递归边界最大值最小值的传递 我的代码测试用例1测试用例2 前言 BST是二叉树一个经典应用&#xff0c;我们常常将其用于数据的查找以及构建平衡二叉树等。今天我所做的题目是验证一颗二叉树是否为二叉搜索树&…

MATLAB实现果蝇算法优化BP神经网络预测分类(FOA-BP)

果蝇算法&#xff08;Fruit Fly Optimization Algorithm, FFOA&#xff09;是一种启发式优化算法&#xff0c;受果蝇觅食行为的启发。将其应用于优化BP神经网络&#xff0c;主要是为了寻找BP神经网络中的最佳权重和偏置值。以下是一个基本的流程&#xff1a; 初始化&#xff1a…

上班族小张的副业之路:下班后的水牛社赚钱故事

在快节奏的都市生活中&#xff0c;上班族小张每天忙碌于办公室与家庭之间&#xff0c;重复着朝九晚五的生活。然而&#xff0c;他内心总渴望寻找一种既能充实生活&#xff0c;又能增加收入的副业方式。直到有一天&#xff0c;他发现了水牛社——一个为他提供丰富副业资源和机会…

信息时代的智慧导航:高效搜索、信息筛选与信任构建的全面指南!

文章目录 一、高效搜索&#xff1a;快速定位目标信息的秘诀二、信息筛选&#xff1a;去伪存真&#xff0c;找到有价值的信息三、信任构建&#xff1a;深入了解与直接沟通《搜索之道&#xff1a;信息素养与终身学习的新引擎》亮点内容简介目录获取方式 随着科技的飞速发展&#…

jenkins汉化不完全问题解决

jenkins安装完Localization:Chinese(Simplified)中文语言包后&#xff0c;发现是出现汉化不完全或者部分汉化的情况&#xff0c;如下图&#xff1a; 解决方法&#xff1a; 启动命令中指定语言 -Duser.languageen_US.UTF-8 或者 -Duser.languageC.UTF-8原因分析&#xff1a;安…

网上招聘系统的设计与实现参考论文(论文 + 源码)

【免费】网上招聘系统的设计与实现.zip资源-CSDN文库https://download.csdn.net/download/JW_559/89251636 网上招聘系统的设计与实现 摘 要 随着时代的发展&#xff0c;中国的互联网技术愈加成熟&#xff0c;已经有越来越多的社会群体开始学会使用互联网技术&#xff0c;整个…

STM32定时器的OC比较和PWM

系列文章目录 STM32单片机系列专栏 C语言术语和结构总结专栏 文章目录 1. 输出比较(OC) 2. PWM 3. PWM的输出 3.1 高级定时器 3.2 通用定时器 4. PWM的输出结构 5. 代码示例 5.1 PWM.c 5.2 PWM.h 5.3 main.c 这篇文章解释了TIM定时器的内部时钟和外部时钟的使用&a…

头歌:Spark的安装与使用

第1关&#xff1a;Scala语言开发环境的部署 相关知识 Scala是一种函数式面向对象语言&#xff0c;它融汇了许多前所未有的特性&#xff0c;而同时又运行于JVM之上。随着开发者对Scala的兴趣日增&#xff0c;以及越来越多的工具支持&#xff0c;无疑Scala语言将成为你手上一件…