SpringCloud中的Hystrix与Sentinel组件

一、前置知识

1.1 微服务架构的高并发问题==》雪崩效应

1.1.1 产生原因

在微服务架构中,一个请求需要调用多个服务是非常常见的。如客户端访问A服务,而A服务需要调用B 服务,B服务需要调用C服务,由于网络原因或者自身的原因,如果B服务或者C服务不能及时响应,A服 务将处于阻塞状态,直到B服务C服务响应。此时若有大量的请求涌入,容器的线程资源会被消耗完毕, 导致服务瘫痪。服务与服务之间的依赖性,故障会传播,造成连锁反应,会对整个微服务系统造成灾难 性的严重后果,这就是服务故障的“雪崩”效应

1.1.2 解决方法

1.1.2.1 服务隔离

服务隔离的分类:
1. 线程池隔离
2. 信号量隔离

1.1.2.2 熔断降级

在互联网系统中,当下游服务因访问压 力过大而响应变慢或失败,上游服务为了保护系统整体的可用性,可以暂时切断对下游服务的调用。这 种牺牲局部,保全整体的措施就叫做熔断。

1.1.2.3 服务限流

限流可以认为服务降级的一种,限流就是限制系统的输入和输出流量已达到保护系统的目的。一般来说系统的吞吐量是可以被测算的,为了保证系统的稳固运行,一旦达到的需要限制的阈值,就需要限制流量并采取少量措施以完成限制流量的目的。比方:推迟解决,拒绝解决,或者者部分拒绝解决

以上的解决方法 自己实现较为困难,而大佬们又很贴心,给我们做好了实现了这些的组件Hystrix或者Sentinel

二 Hystrix组件

2.1 Hystrix组件的基础

2.1.1 Hystrix组件是啥?

Hystrix是由Netflix开源的一个延迟和容错库,用于隔离访问远程系统、服务或者第三方库,防止级联失 败,从而提升系统的可用性与容错性。

2.1.2 Hystrix组件含有的特性

  1. 包裹请求:使用HystrixCommand包裹对依赖的调用逻辑,每个命令在独立线程中执行。这使用 了设计模式中的“命令模式”
  2. 跳闸机制:当某服务的错误率超过一定的阈值时,Hystrix可以自动或手动跳闸,停止请求该服务 一段时间。
  3. 资源隔离:Hystrix为每个依赖都维护了一个小型的线程池(或者信号量)。如果该线程池已满, 发往该依赖的请求就被立即拒绝,而不是排队等待,从而加速失败判定
  4. 监控:Hystrix可以近乎实时地监控运行指标和配置的变化,例如成功、失败、超时、以及被拒绝 的请求等
  5. 回退机制:当请求失败、超时、被拒绝,或当断路器打开时,执行回退逻辑。回退逻辑由开发人员 自行提供,例如返回一个缺省值
  6. 自我修复:断路器打开一段时间后,会自动进入“半开”状态。

2.1.3 Hystrix基于Rest服务调用实现服务熔断

注意事项!!:
  1. 开启熔断使用的@EnableCircuitBreaker
@EntityScan("cn.itcast.entity") 
@SpringCloudApplication
public class OrderApplication {
//创建RestTemplate对象
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
        return new RestTemplate();
    }
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
} }
//我们类上的注解越来越多,在微服务中,经常会引入上面的三个注解,于是Spring就提供了 一个组合注解:@SpringCloudApplication
  1. 配置熔断降级业务逻辑
    注意:
    1. 熔断的降级逻辑方法必须跟正常逻辑方法保证:相同的参数列表和返回值声明。
    2. 在 findProduct 方法上 HystrixCommand(fallbackMethod = “findProductFallBack”) 用来 声明一个降级逻辑的方法
    进阶:
    1. 默认的Fallback:我们可以 把Fallback配置加在类上,实现默认fallback:通过@DefaultProperties
    2. 超时设置
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
			timeoutInMilliseconds: 2000

2.1.3 Hystrix基于Feign服务调用实现服务熔断

实现步骤
1. 创建工程
2. 修改application.yml在Fegin中开启hystrix
Feign中已经内置了hystrix,但是默认是关闭的需要在工程的 application.yml 中开启对hystrix的 支持

feign:
	hystrix: #在feign中开启hystrix熔断
    	enabled: true
3. 配置FeignClient接口的实现类
	基于Feign实现熔断降级,那么降级方法需要配置到FeignClient接口的实现类中
/**
* 实现自定义的ProductFeginClient接口 * 在接口实现类中编写熔断降级方法 */
@Component
public class ProductFeginClientCallBack implements ProductFeginClient {
	/**
	* 降级方法 */
	public Product findById(Long id) {
	Product product = new Product(); product.setId(-1l); 			product.setProductName("熔断:触发降级方法"); return product;
} }
4. 修改FeignClient添加hystrix熔断
	@FeignClient注解中添加降级方法
//指定需要调用的微服务名称 @FeignClient(name="shop-service-product",fallback = ProductFeginClientCallBack.class)
public interface ProductFeginClient {
//调用的请求路径
@RequestMapping(value = "/product/{id}",method = RequestMethod.GET)
 public Product findById(@PathVariable("id") Long id);
}
	@FeignClient注解中以fallback声明降级方法

2.2 Hystrix组件的进阶

2.2.1 Hystrix监控平台

Hystrix还提供了近乎实时的监控,状态会暴露在Actuator提供的/health端点中。只需为项目添加 spring-boot-actuator 依赖,重启项目,访问http://localhost:9001/actuator/hystrix.stream ,即可看到实时的监控数据。

2.2.1.1 搭建Hystrix DashBoard监控
  1. 导入依赖
  2. 添加EnableHystrixDashboard 注解
  3. 访问测试
2.2.1.2 断路器聚合监控Turbine
2.2.1.2.2 来源

在微服务架构体系中,每个服务都需要配置Hystrix DashBoard监控。如果每次只能查看单个实例的监 控数据,就需要不断切换监控地址,这显然很不方便。要想看这个系统的Hystrix Dashboard数据就需 要用到Hystrix Turbine。

2.2.1.2.2 作用

Turbine是一个聚合Hystrix 监控数据的工具,他可以将所有相关微服务的 Hystrix 监控数据聚合到一起,方便使用

2.2.1.2.2 实现步骤

1、搭建TurbineServer
2、配置多个微服务的hystrix监控

server:
  port: 8031
spring:
  application:
    name: microservice-hystrix-turbine
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true
turbine:
# 要监控的微服务列表,多个用,分隔 appConfig: shop-service-order clusterNameExpression: "'default'"
1. eureka相关配置 : 指定注册中心地址
2. turbine相关配置:指定需要监控的微服务列表

3、配置启动类

@SpringBootApplication
@EnableTurbine
@EnableHystrixDashboard
public class TurbineServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(TurbineServerApplication.class, args);
} }

4、测试

2.2.2 熔断器状态

熔断器有三个状态 CLOSED 、 OPEN 、 HALF_OPEN 熔断器默认关闭状态,当触发熔断后状态变更为 OPEN,在等待到指定的时间,Hystrix会放请求检测服务是否开启,这期间熔断器会变为HALF_OPEN 半
1. Closed:关闭状态(断路器关闭),所有请求都正常访问。代理类维护了最近调用失败的次数, 如果某次调用失败,则使失败次数加1。如果最近失败次数超过了在给定时间内允许失败的阈值, 则代理类切换到断开(Open)状态。此时代理开启了一个超时时钟,当该时钟超过了该时间,则切 换到半断开(Half-Open)状态。该超时时间的设定是给了系统一次机会来修正导致调用失败的错 误。
2. Open:打开状态(断路器打开),所有请求都会被降级。Hystix会对请求情况计数,当一定时间 内失败请求百分比达到阈值,则触发熔断,断路器会完全关闭。默认失败比例的阈值是50%,请求 次数最少不低于20次。
3. Half Open:半开状态,open状态不是永久的,打开后会进入休眠时间(默认是5S)。随后断路 器会自动进入半开状态。此时会释放1次请求通过,若这个请求是健康的,则会关闭断路器,否则 继续保持打开,再次进行5秒休眠计时。

2.2.3 熔断器的隔离策略

2.2.3.1 线程池隔离

使用一个线程池来存储当前的请求,线程池对请求作处理,设置任务返回处理超 时时间,堆积的请求堆积入线程池队列。

2.2.3.2 信号量隔离

使用一个原子计数器(或信号量)来记录当前有多少个线程在运行,请求来先判 断计数器的数值,若超过设置的最大线程个数则丢弃改类型的新请求,若不超过则执行计数操作请 求来计数器+1,请求返回计数器-1。这种方式是严格的控制线程且立即返回模式,无法应对突发 流量(流量洪峰来临时,处理的线程超过数量,其他的请求会直接返回,不继续去请求依赖的服务)

2.2.3.3 两种策略功能支持的对比

请添加图片描述

2.2.4 Hystrix的核心源码

1Hystrix 底层基于 RxJava,RxJava 是响应式编程开发库
Hystrix主要有4种调用方式:
	1. toObservable() 方法 :未做订阅,只是返回一个Observable 。
	2. observe() 方法 :调用 #toObservable() 方法,并向 Observable 注册 rx.subjects.ReplaySubject 发起订阅。
	3. queue() 方法 :调用 #toObservable() 方法的基础上,调用:Observable#toBlocking() 和 BlockingObservable#toFuture() 返回 Future 对象
	4. execute() 方法 :调用 #queue() 方法的基础上,调用 Future#get() 方法,同步返回 #run() 的执 行结果。
执行逻辑
  1. 每次调用创建一个新的HystrixCommand,把依赖调用封装在run()方法中.
  2. 执行execute()/queue做同步或异步调用.
  3. 判断熔断器(circuit-breaker)是否打开,如果打开跳到步骤8,进行降级策略,如果关闭进入步骤.
  4. 判断线程池/队列/信号量是否跑满,如果跑满进入降级步骤8,否则继续后续步骤.
  5. 调用HystrixCommand的run方法.运行依赖逻辑,依赖逻辑调用超时,进入步骤8.
  6. 判断逻辑是否调用成功。返回成功调用结果;调用出错,进入步骤8.
  7. 计算熔断器状态,所有的运行状态(成功, 失败, 拒绝,超时)上报给熔断器,用于统计从而判断熔断器 状态.
  8. getFallback()降级逻辑。以下四种情况将触发getFallback调用:
    1. run()方法抛出非 HystrixBadRequestException异常。
    2. run()方法调用超时
    3. 熔断器开启拦截调用
    4. 线程池/队列/信号量是否跑满
    5. 没有实现getFallback的Command将直接抛出异常,fallback降级逻辑调用成功直接返回,降 级逻辑调用失败抛出异常.
  9. 返回执行成功结果

三 Sentinel组件

3.1概念

3.1.1是个啥?

		Sentinel 是阿里巴巴开源的一款断路器实现

3.1.2 含有特性?

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

3.1.2 Sentinel与Hystrix的区别

请添加图片描述

3.1.3 Sentinel中名词解释

	1. Sentinel 核心库
	2. Dashboard
	3. Sentinel 来进行熔断保护
		1. 定义资源
			资源:可以是任何东西,一个服务,服务里的方法,甚至是一段代码
		2. 定义规则
			规则:Sentinel 支持以下几种规则:流量控制规则、熔断降级规则、系统保护规则、来源访问控制规则和 热点参数规则。Sentinel 的所有规则都可以在内存态中动态地查询及修改,修改之后立即生效
		3. 检验规则是否生效

3.1.4 Sentinel中的管理控制台

	下载启动控制台
		(1)获取 Sentinel 控制台
		(2)启动
	客户端能接入控制台
		(1) 引入JAR包
		(2)配置启动参数
	查看机器列表以及健康情况

3.1.5 基于Sentinel的服务保护

3.1.5.1 通用资源保护

		实现步骤
			1、搭建工程
			2、引入依赖
			3、 配置熔断降级方法

3.1.5.2 Rest实现熔断

		Spring Cloud Alibaba Sentinel 支持对 RestTemplate 的服务调用使用 Sentinel 进行保护,在构造RestTemplate bean的时候需要加上 @SentinelRestTemplate 注解。
		注意:@SentinelRestTemplate 注解中 ExceptionUtil 的 handleException 属性对应的方法 声明如下:
 /**
* 熔断降级 */
public class ExceptionUtil {
//限流熔断业务逻辑
    public static SentinelClientHttpResponse  handleBlock(HttpRequest request,
byte[] body,
                                                     ClientHttpRequestExecution
execution, BlockException ex) {
System.err.println("Oops: " + ex.getClass().getCanonicalName()); return new SentinelClientHttpResponse("限流熔断降级");
}
//异常熔断业务逻辑
  public static SentinelClientHttpResponse  handleFallback(HttpRequest
request, byte[] body,
                                                    ClientHttpRequestExecution
execution, BlockException ex) {
System.err.println("fallback: " + ex.getClass().getCanonicalName()); return new SentinelClientHttpResponse("异常熔断降级");
} }
 
		Sentinel RestTemplate 限流的资源规则提供两种粒度
			httpmethod:schema://host:port/path :协议、主机、端口和路径
			httpmethod:schema://host:port :协议、主机和端口

3.1.5.3 Feign实现熔断

		实现步骤
			(1) 引入依赖
			(2) 开启sentinel 支持
feign:
  sentinel:
    enabled: true
			(3)配置FeignClient
//指定需要调用的微服务名称 @FeignClient(name="shop-service-product",fallback = ProductFeginClientCallBack.class)
public interface ProductFeginClient {
//调用的请求路径
@RequestMapping(value = "/product/{id}",method = RequestMethod.GET) public Product findById(@PathVariable("id") Long id);
}
				和使用Hystrix的方式基本一致,需要配置FeignClient接口以及通过fallback 指定熔断降级方法
			(4)配置熔断方法
/**
* 实现自定义的ProductFeginClient接口 * 在接口实现类中编写熔断降级方法 */
@Component
public class ProductFeginClientCallBack implements ProductFeginClient {
/**
* 降级方法 */
public Product findById(Long id) {
Product product = new Product(); product.setId(-1l); product.setProductName("熔断:触发降级方法"); return product;
} }
 
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值