SpringCloud基础知识【Hystrix熔断器】
创始人
2024-01-21 00:43:11
0

SpringCloud基础知识【Hystrix熔断器】

  • 1. Hystrix概述
  • 2. Hystix-隔离
    • 2.1 线程池隔离
    • 2.2 信号量隔离
    • 2.3 Hystix隔离小结
  • 3. Hystix-降级
    • 3.1 服务提供方降级
    • 3.2 消费方降级
    • 3.3 Hystix降级小结
  • 4. Hystix-熔断
    • 4.1 代码演示
    • 4.1 熔断监控
  • 5. Hystix-限流

1. Hystrix概述

Hystix,是Netflix开源的一个延迟和容错库,用于隔离访问远程服务、第三方库,防止出现级联失败(雪崩)。

  • 雪崩:一个服务失败。导致整条链路的服务都失败的情形。

在这里插入图片描述
在这里插入图片描述

那么如何预防雪崩的出现呢?

  • Hystix为我们提供了隔离降级熔断限流等方法防止雪崩的发生。

2. Hystix-隔离

资源隔离要解决的核心的问题:就是将多个依赖服务的调用分别隔离到各自的资源池内。

  • 避免对某一个依赖服务的调用,因为依赖服务的接口调用的延迟或者失败,导致服务所有的线程资源全部耗费在这个服务的接口调用上
  • 一旦某个服务的线程资源全部耗尽的话,可能就导致服务就会崩溃,甚至说这种故障会不断蔓延。如下图所示:
    在这里插入图片描述

2.1 线程池隔离

线程池隔离:适合绝大多数的场景,Hystix默认采用线程池隔离

  • 如下图所示,A 服务将Threadpool中拆分成Threadpool-BThreadpool-CThreadpool-D3个单独对B\C\D进行服务。
  • 各线程池相互独立。一个服务[C]挂掉并不会引起整条链路都失败的情况发生。

在这里插入图片描述

线程池隔离优缺点

  优点∶

  1. 使用线程池隔离可以完全隔离依赖的服务(例如图中的 B、C、D服务),请求线程可以快速放回
  2. 当线程池出现问题时,线程池隔离是独立的,不会影响其他服务和接口。
  3. 当失败的服务再次变得可用时,线程池将清理并可立即恢复,而不需要一个长时间的恢复。
  4. 独立的线程池提高了并发性。

 缺点∶

  1. 线程池隔离的主要缺点是它们增加计算开销(CPU)。每个命令的执行涉及到排队、调度和上下文切换都是在一个单独的线程上运行的。

2.2 信号量隔离

信号量隔离:适合与对内部的一些比较复杂的业务逻辑的访问,而不是对外部依赖的访问。

  • 一个线程池、但对不同的服务上加上一个阀门(访问的次数)。超过该数量,就拒绝后续的服务。

在这里插入图片描述

2.3 Hystix隔离小结

是否有线程切换是否支持异步是否支持超时是否支持熔断是否支持限流开销
线程池
信号量×××

什么情况下,用线程池隔离?

  1. 请求并发量大,并且耗时长(计算量大,或读数据库)
  2. 原因:可以保证大量的容器(tomcat)线程可用,不会由于服务原因,一直处于阻塞或等待状态,快速失败返回。

什么情况下,用信号量隔离?

  1. 请求并发量大,并且耗时短(计算量小,或读缓存)
  2. 原因:这类服务的返回通常会非常的快,不会占用容器线程太长时间,而且也减少了线程切换的一些开销,提高了缓存服务的效率。

3. Hystix-降级

Hystix降级:当服务发生异常或调用超时,返回默认处理方案(默认数据)

在这里插入图片描述

3.1 服务提供方降级

Hystrix初始代码Fiegn初始代码一样,这里就不再赘述。

在这里插入图片描述在这里插入图片描述
  1. 在服务提供方(hystrix-provider),引入 hystrix依赖
  2. 定义降级方法
  3. 使用@HystrixCommand 注解配置降级方法
  4. 在启动类上开启Hystrix功能:@EnableCircuitBreaker

在这里插入图片描述
实例操作

  • 引入 hystrix依赖

org.springframework.cloudspring-cloud-starter-netflix-hystrix

  • 在服务提供方启动类开启开启Hystrix功能
package com.itheima.provider;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;@EnableEurekaClient //该注解 在新版本中可以省略
@SpringBootApplication@EnableCircuitBreaker //开启Hystrix功能
public class ProviderApp {public static void main(String[] args) {SpringApplication.run(ProviderApp.class,args);}
}
  • 因为后续会有消费方调用提供方中controller中提供的方法接口,那么如果该接口出异常,我们就需要为其提供一个降级方法。
package com.itheima.provider.controller;import com.itheima.provider.domain.Goods;
import com.itheima.provider.service.GoodsService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.Date;/*** Goods Controller 服务提供方*/@RestController
@RequestMapping("/goods")
public class GoodsController {@Autowiredprivate GoodsService goodsService;@Value("${server.port}")private int port;/*** 降级:*  1. 出现异常*  2. 服务调用超时*      * 默认1s超时**  @HystrixCommand(fallbackMethod = "findOne_fallback")*      fallbackMethod:指定降级后调用的方法名称*/@GetMapping("/findOne/{id}")@HystrixCommand(fallbackMethod = "findOne_fallback",commandProperties = {//设置Hystrix的超时时间,默认1s@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value = "3000")})public Goods findOne(@PathVariable("id") int id){//降级情况1.异常int i = 3/0;//降级情况2.服务调用超时try {//2. 休眠2秒Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}Goods goods = goodsService.findOne(id);goods.setTitle(goods.getTitle() + ":" + port);//将端口号,设置到了 商品标题上return goods;}/*** 定义降级方法:*  1. 方法的返回值需要和原方法一样*  2. 方法的参数需要和原方法一样*/public Goods findOne_fallback(int id){//findOne的降级方法。Goods goods = new Goods();goods.setTitle("降级了~~~");return goods;}}

在这里插入图片描述

3.2 消费方降级

  1. feign 组件已经集成了hystrix组件。
  2. 定义feign调用接口实现类,复写方法,即降级方法
    在这里插入图片描述
  3. @FeignClient注解中使用fallback 属性设置降级处理类。
  4. 配置开启 feign.hystrix.enabled = true

在这里插入图片描述
实例操作

  • 服务消费方的application.yml中添加下面代码:开启feign对hystrix的支持
# 开启feign对hystrix的支持
feign:hystrix:enabled: true
  • 在GoodsFeignClient 接口上的@FeignClient注解中使用fallback 属性设置降级处理类。
package com.itheima.consumer.feign;import com.itheima.consumer.domain.Goods;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;@FeignClient(value = "HYSTRIX-PROVIDER",fallback = GoodsFeignClientFallback.class)
public interface GoodsFeignClient {@GetMapping("/goods/findOne/{id}")public Goods findGoodsById(@PathVariable("id") int id);}
  • 实现降级处理类
package com.itheima.consumer.feign;import com.itheima.consumer.domain.Goods;
import org.springframework.stereotype.Component;/*** Feign 客户端的降级处理类* 1. 定义类 实现 Feign 客户端接口* 2. 使用@Component注解将该类的Bean加入SpringIOC容器*/
@Component
public class GoodsFeignClientFallback implements GoodsFeignClient {@Overridepublic Goods findGoodsById(int id) {Goods goods = new Goods();goods.setTitle("又被降级了~~~");return goods;}
}

在这里插入图片描述

3.3 Hystix降级小结

注意:

  • 当服务提供方和服务的消费方都配置了降级时,当失败后(出现异常、服务调用超时)只有服务提供方的降级会生效

  • 原因:当出现异常,服务提供方已经降过级,降过级后,返回的数据是正常的数据。那么这时服务消费方就不用再次被降级。

4. Hystix-熔断

Hystrix 熔断机制,用于监控微服务调用情况,当失败的情况达到预定的阈值(5秒失败20次),会打开断路器,拒绝所有请求,不管请求降级与否,直到服务恢复正常为止。

  • circuitBreaker.sleepWindowlnMilliseconds:监控时间
  • circuitBreaker.requestVolumeThreshold:失败次数
  • circuitBreaker.errorThresholdPercentage:失败率

在这里插入图片描述

4.1 代码演示

在服务提供方(hystrix-provider)controlloer包下的GoodsControlloer中写(默认该机制已开启)

package com.itheima.provider.controller;import com.itheima.provider.domain.Goods;
import com.itheima.provider.service.GoodsService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.Date;/*** Goods Controller 服务提供方*/@RestController
@RequestMapping("/goods")
public class GoodsController {@Autowiredprivate GoodsService goodsService;@Value("${server.port}")private int port;@GetMapping("/findOne/{id}")@HystrixCommand(fallbackMethod = "findOne_fallback",commandProperties = {//设置Hystrix的超时时间,默认1s@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value = "3000"),//监控时间 默认5000 毫秒@HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds",value = "5000"),//失败次数。默认20次@HystrixProperty(name="circuitBreaker.requestVolumeThreshold",value = "20"),//失败率 默认50%@HystrixProperty(name="circuitBreaker.errorThresholdPercentage",value = "50")})public Goods findOne(@PathVariable("id") int id){//如果id == 1 ,则出现异常,id != 1 则正常访问if(id == 1){//1.造个异常int i = 3/0;}Goods goods = goodsService.findOne(id);goods.setTitle(goods.getTitle() + ":" + port);//将端口号,设置到了 商品标题上return goods;}/*** 定义降级方法:*  1. 方法的返回值需要和原方法一样*  2. 方法的参数需要和原方法一样*/public Goods findOne_fallback(int id){Goods goods = new Goods();goods.setTitle("降级了~~~");return goods;}}

4.1 熔断监控

  • Hystrix提供了 Hystrix-dashboard 功能,用于实时监控微服务运行状态。
  • 但是 Hystrix-dashboard 只能监控一个微服务
  • Netflix还提供了 Turbine ,进行聚合监控

在这里插入图片描述
聚合监控

  • 使用Turbine ,进行聚合监控:SpringCloud基础知识【Hystrix熔断器–Turbine搭建步骤】

5. Hystix-限流

在高并发访问下,由于系统资源有限,必须对访问量进行控制。

  • Hystrix提供了限流功能,在springcloud架构的系统中,可以在网关启用Hystrix,进行限流处理,每个微服务也可以各自启用Hystrix进行限流。
  • Hystrix默认使用线程隔离模式,可以通过线程数+队列大小进行限流
hystrix:threadpool:default:coreSize: 200 #并发执行的最大线程数,默认10maxQueueSize: 1000 #BlockingQueue的最大队列数,默认值-1queueSizeRejectionThreshold: 800 #即使maxQueueSize没有达到,达到queueSizeRejectionThreshold该值后,请求也会被拒绝,默认值5

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...