04-Hystrix

news2024/10/7 6:50:41

服务熔断Hystrix

1. Hystrix是什么

分布式系统环境下,服务间类似依赖非常常见,一个业务调用通常依赖多个基础服务。如下图,对于同步调用,当库存服务不可用时,商品服务请求线程被阻塞,当有大批量请求调用库存服务时,最终可能导致整个商品服务资源耗尽,无法继续对外提供服务。并且这种不可用可能沿请求调用链向上传递,这种现象被称为雪崩效应。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VUVnZy2J-1671968360888)(images/42.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y7HsW098-1671968360889)(images/43.png)]

为了解决此问题,微服务架构中引入了一种叫熔断器的服务保护机制。

熔断器也有叫断路器,他们表示同一个意思,最早来源于微服务之父Martin Fowler的论文CircuitBreaker一文。“熔断器”本身是一种开关装置,用于在电路上保护线路过载,当线路中有电器发生短路时,能够及时切断故障电路,防止发生过载、发热甚至起火等严重后果。

微服务架构中的熔断器,就是当被调用方没有响应,调用方直接返回一个错误响应即可,而不是长时间的等待,这样避免调用时因为等待而线程一直得不到释放,避免故障在分布式系统间蔓延;

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

2.引起雪崩效应常见场景

硬件故障:如服务器宕机,机房断电,光纤被挖断等

流量激增:如异常流量,重试加大流量等

缓存击穿:一般发生在应用重启,所有缓存失效时,以及短时间内大量缓存失效时。大量的缓存不命中,使请求直击后端服务,造成服务提供者超负荷运行,引起服务不可用

程序 BUG:如程序逻辑导致内存泄漏,JVM 长时间 FullGC 等

同步等待:服务间采用同步调用模式,同步等待造成的资源耗尽

3. Hystrix快速入门

当有服务调用的时候,才会出现服务雪崩,所以Hystrix常和OpenFeign,Ribbon一起出现。

在SpringCloud中使用熔断器Hystrix, 构建产品服务product-service,订单服务order-service

3.1创建注册中心eurkea-server

3.2设置eurke-server中的application的配置

server:
  port: 9100
spring:
  application:
    name: eureka-server
eureka:
  client:
    register-with-eureka: false #由于我们目前创建的应用是一个服务注册中心,而不是普通的应用,默认情况下,这个应用会向注册中心(也是它自己)注册它自己,设置为false表示禁止这种自己向自己注册的默认行为
    fetch-registry: false #由于我们目前创建的应用是一个服务注册中心,而不是普通的应用,默认情况下,这个应用会向注册中心(也是它自己)注册它自己,设置为false表示禁止这种自己向自己注册的默认行为

3.3产品服务product-service(提供者)提供的服务

@RequestMapping("/product")  
 public String queryProduct(){
   return "商品查询成功,小米笔记本,质量杠杠滴";
 }

3.4application文件配置内容

server:
  port: 8081
spring:
  application:
    name: product-service
eureka:
  client:
    service-url:
      defaultZone: http://localhost:9100/eureka

3.5创建消费者项目order-service中添加hystrix依赖

   <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

3.6在入口类@EnableCircuitBreaker注解开启断路器功能

也可以使用一个名为@SpringCloudApplication的注解代替主类上的三个注解;

@SpringCloudApplication
@EnableCircuitBreaker
@EnableDiscoveryClient
@EnableFeignClients 
public class OrderserviceApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderserviceApplication.class, args);        
    }   
 }

3.7.开启熔断保护

SpringCloud Fegin默认已为Feign整合了hystrix,所以添加Feign依赖后就不用在添加hystrix,

按照以下步骤开发:
(1)order-service中application文件中添加以下配置,开启hystrix

#在feign中开启熔断服务
feign:
    circuitbreaker:
        enabled: true

3.8自定义一个FeignClient接口的实现类

这个类就是熔断降级触发的逻辑代码

@Component
public class ProductFeignClientCallback  implements  ProductFeignClient{
    @Override //降级服务的实现
    public String queryProduct() {
        return "产品服务正在升级中,暂时不可用,请客官耐心等待....";
    }
}
/*fallback =ProductFeignImpl.class 熔断调用 实现类*/
@FeignClient(name = "product-service",fallback =ProductFeignClientCallback.class)
public interface ProductFeign {

    @GetMapping("/product")
    String queryProduct();

    @GetMapping("/product/{id}") //务必和原始服务提供者方法保持一致
    String detail(@PathVariable  Integer id);

    @PostMapping("/add")
    String addProduct(@RequestParam("id") Integer id,@RequestParam("name") String name);
}

3.9使用RestTemplate调用,实现熔断

启动类添加注解@EnableCircuitBreaker

   @GetMapping("/orderProduct")
    @HystrixCommand(fallbackMethod = "productFallback")
    public String orderProduct()
    {
        String url="http://product-service/product";
        return "产品订购完成:"+restTemplate.getForObject(url,String.class);
    }

    public String productFallback()
    {
        return "抢购的人太多了,请稍后再来...";
    }

注意:

熔断的方法名可以不需要和主方法名保持一致
但是错误的方法返回值类型必须和主方法返回值类型保持一致
错误错误的方法参数类型必须和主方法的参数类型保持一致
否则会报fallbackMethod找不到的异常

3.9在接口上添加熔断类型的注解

@FeignClient(name="product-service",fallback = ProductFeignClientCallback.class)
public interface ProductFeignClient {
}

3.10执行测试

(1)执行测试,当产品服务正常工作时,订单服务正确调用产品服务

(2)关闭产品服务,则执行消费者提供的熔断降级方法

4.常用配置

server:
    port: 8081
spring:
    application:
        name: consumer-service
eureka:
    client:
        service-url:
            defaultZone: http://localhost:8761/eureka/
        fetch-registry: true
        register-with-eureka: true
    instance:
        instance-id: ${spring.application.name}:${server.port}
        prefer-ip-address: true
feign:
    circuitbreaker:
        enabled: true
    client:
        config:
            default:
                connectTimeout: 5000
                readTimeout: 5000
                loggerLevel: BASIC
hystrix:
    command:
        default:
            execution:
                isolation:
                    strategy: THREAD  # 隔离方式 THREAD线程隔离集合和SEMAPHORE信号量隔离级别
                    thread:
                        timeoutInMilliseconds: 1000  # 调用超时时间
                    semaphore:
                        maxConcurrentRequests: 1000  # 信号量隔离是最大并发请求数
            circuitBreaker:
                requestVolumeThreshold: 3       #失败次数(阀值)
                errorThresholdPercentage: 60 #失败率
                sleepWindowInMilliseconds: 5000  # 断路器处理打开状态后 多久变成半开
            metrics:
                rollingStats:
                    timeInMilliseconds: 10000  # 统计窗口时间

5.隔离方式

hystrix的一项核心功能,就是所谓的资源隔离,资源隔离要解决的最核心的问题,就是将多个依赖服务的调用分别隔离到各自的资源池内。避免对某一个依赖服务的调用,因为依赖服务的接口调用的延迟或者失败,导致服务所有的线程资源全部耗费在这个服务的接口调用上。一旦某个服务的线程资源全部耗尽的话,可能就导致服务就会崩溃,甚至说这种故障会不断蔓延.hystrix支持两种方式的资源隔离

5.1线程池隔离(默认的方式)

隔离是通过线程池来做到的,也就是说他的隔离粒度是线程池。一个请求进来都经过一个线程池。

当前端发起请求过来到服务A或者B之后,服务A和服务B是通过线程池隔离的。服务A是否熔断,是否正常都和服务B无关。

他其实是一个异步编程,用线程池将后面的服务包裹了起来,至于服务内部tomcate的线程运行怎么样是无关的。他适合于绝大多数的场景,对于一些超时的场景都非常好用。但是既然是通过线程池来操作的,不可避免的就是线程之间的计算开销,以及线程上下文的切换,调度消耗。

适合绝大多数的场景。特别是 对其他服务的网络请求与调用存在 timeout 问题时。
如果当前请求的服务,需要耗时很长才能完成服务的响应,为了防止超时,可以使用的线程池杜绝服务因为超时出现问题。

5.2信号量隔离

线程隔离会带来线程开销,有些场景(比如无网络请求场景)可能会因为用开销换隔离得不偿失,为此hystrix提供了信号量隔离,当服务的并发数大于信号量阈值时将进入fallback 。

隔离是通过信号量来做到的。其实是一个计数器。一个请求进来就会减少一个信号,一个请求完成就会增加一个信号。信号量的调用是同步的,也就是说他会阻塞直到请求回来。

适合与对内部的一些比较复杂的业务逻辑的访问,而不是对外部依赖的访问。
像这种访问系统内部的代码,其实不涉及网络请求,那么只要做信号量的普通限流就可以了,因为不需要去捕获 timeout 类似的问题,程序在做 “算法+数据结构” 等操作时如果效率不是太高,并发量突然太高,因为比较微耗时,导致很多线程卡在这里的话,不太好,所以进行一个基本的资源隔离和访问,避免内部复杂的低效率的代码,导致大量的线程被hang住。

6.Hystrix服务熔断开启条件

熔断机制是应对雪崩效应的一种微服务链路保护机制,一般来说,每个服务都需要熔断机制的。如高压电路中,如果某个地方的电压过高,熔断器就会熔断,对电路进行保护。在微服务架构中,熔断机制也是起着类似的作用。

当链路的某个微服务不可用,或响应超时,或宕机,或异常时,进而熔断该节点微服务的调用,快速返回错误的响应信息。当检测到该节点微服务调用响应正常后,恢复调用链路。

熔断器开启的条件

当请求达到阀值时候:默认 10 秒内 20 次请求,当请求失败率达到默认 50% 的时,此时断路器将会开启,所有的请求都不会执行

断路器关闭的条件

当断路器开启 5 秒(默认)时,这时断路器是半开状态, 会允许其中一个请求执行

当链路的某个微服务不可用,或响应超时,或宕机,或异常时,进而熔断该节点微服务的调用,快速返回错误的响应信息。当检测到该节点微服务调用响应正常后,恢复调用链路。

熔断器开启的条件

当请求达到阀值时候:默认 10 秒内 20 次请求,当请求失败率达到默认 50% 的时,此时断路器将会开启,所有的请求都不会执行

断路器关闭的条件

当断路器开启 5 秒(默认)时,这时断路器是半开状态, 会允许其中一个请求执行

如果执行成功,则断路器会关闭;如果失败,则继续开启。循环重复这两个流程

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

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

相关文章

SpringBoot-2 读取properties;自动加载127个类原理总结;全部加载,按需配置

读取properties 方式一&#xff1a;非配置类填写&#xff1a;ComponentConfigurationProperties 1)建立bean&#xff1a; /只有在容器中的组件才拥有springboot提供的强大功能 Component ConfigurationProperties(prefix "mycar") public class Car {private Stri…

【机器学习】模型评估与选择

模型评估与选择 目录一、评估方法1、留出法2、交叉验证法3、自助法二、性能度量1、错误率与准确率2、查准率、查全率阈值对查准率、查全率的影响3、F1度量&#xff08;基于查准率与查全率的调和平均&#xff09;4、P-R Curve5、ROC CurvePRC和ROC的选用准则PRC和ROC的差异6、代…

python 中文转带音调的拼音

python 中文转带音调的拼音 前言python 中文转带音调的拼音1、1.1 安装pinyin模块1.2 试验1.3 效果图1.4 代码实现前言 今天整理中药材,每个药材上标上带音调的拼音,查了些,有的易形成乱码,如Shān Mi Dōnɡ,想到python自已动手转算了 python 中文转带音调的拼音 1、 …

(五)汇编语言——[bx]和loop指令

目录 [...]与&#xff08;...&#xff09; [...] &#xff08;...&#xff09; idata Loop指令 段前缀 总结 [...]与&#xff08;...&#xff09; [...] 这个我们其实见过&#xff0c;代表的是一个内存单元&#xff0c;段地址在DS中&#xff0c;偏移地址就是[bx]。 &am…

《图解TCP/IP》阅读笔记(第七章 7.4)—— RIP 路由信息协议

7.4 RIP RIP&#xff08;Routing Information Protocol&#xff0c;路由信息协议&#xff09;&#xff0c;是一种距离向量算法&#xff0c;广泛用于LAN。 该协议将路由控制信息定期&#xff08;30秒一次&#xff09;向全网广播。如果没有收到路由控制信息&#xff0c;连接就会…

【1739. 放置盒子】

来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 描述&#xff1a; 有一个立方体房间&#xff0c;其长度、宽度和高度都等于 n 个单位。请你在房间里放置 n 个盒子&#xff0c;每个盒子都是一个单位边长的立方体。放置规则如下&#xff1a; 你可以把盒子放在地板上的…

筛法(线性筛,厄拉多塞筛)

在前前前前前前…的博客中,我们主要谈了欧拉筛和埃氏筛. 今天我们主要来聊一聊线性筛和厄拉多塞筛(其实和埃氏筛和欧拉筛本质上没区别哎).其实在这两种筛法中厄拉多塞筛最好懂(就连本蒟蒻一看代码就明白了…别看这个名字,容易糊弄人) 首先是厄拉多塞筛"粉墨登场"::…

HRTransNet阅读理解

E. Dual-direction short connection fusion module HRFormer applies transformer blocks to enlarge receptive field of fused feature Frs, and uses exchange units to absorb the merits of multi-scales features. The process is described as: HRFormer使用TRM块来扩…

《教育的目的》笔记——如何让学生通过树木看见森林

目录 作者简介 个人感悟 经典摘录 1、学生所受的训练应该比他们最终投身的专业更为广泛 2、学习新语言用途 3、教师的责任 4、教育的主题 5、学到的有用之物 6、教育目的 7、所有事物都不是静态的、定型的&#xff0c;而是处于形成&#xff08;becoming&#xff09;过…

Merry Xmas | 用Matplotlib画个3D圣诞树送给你!~

1写在前面 Merry Christmas ! &#x1f973; 过完圣诞就要跨年了&#xff0c;希望2023年自己可以一扫霉运&#xff0c;顺顺利利&#xff01;&#xff01;&#xff01;&#x1f618; 从网上抄了个英文的祝福语送给大家&#xff08;主要是懒&#xff09;: &#x1f447; I hope S…

【Unity】VideoPlayer实现视频播放

【Unity】VideoPlayer实现视频播放 背景&#xff1a;开发影院场景需要在荧幕上播放视频 环境&#xff1a;Unity2021.3 VideoPlayer的简单使用&#xff1a;http://t.csdn.cn/K8665 局限&#xff1a;上述方法会使得视频播放窗口强制在相机前&#xff1b; 需求&#xff1a;视频播…

怎么看懂单片机时序图?

本人没有上过单片机相关的专业课&#xff0c;是在《计算机系统结构》里遇见的时序图。由于看不懂加之老师没有专门讲&#xff0c;因此自行查阅了相关的视频和博客。&#xff08;参考视频已放在文末&#xff09; 网上资源贫瘠&#xff0c;不过我也不需要太过深入的知识。 大家…

spring事物使用示例及原理总结

目录 事务示例 示例一 示例二 示例三 示例四 示例五 示例六 事务原理 EnableTransactionManagement 执行代理对象目标方法 事务示例 示例一 在test()方法直接调用abc()方法&#xff0c;并在test()方法添加Transactional&#xff0c;test()和abc()方法分别会更新id…

力扣刷题笔记day10(树的子结构+二叉树镜像+对称的二叉树)

文章目录树的子结构题目思路代码二叉树镜像题目思路代码对称的二叉树题目思路代码树的子结构 输入两棵二叉树A和B&#xff0c;判断B是不是A的子结构。(约定空树不是任意一个树的子结构) B是A的子结构&#xff0c; 即 A中有出现和B相同的结构和节点值。 题目 思路 dfs(A, B) …

二叉树经典算法题目

1.二叉树的前中后序遍历&#xff08;简单&#xff09; 省略 2.二叉树的深度(简单) 输入一棵二叉树的根节点&#xff0c;求该树的深度。从根节点到叶节点依次经过的节点&#xff08;含根、叶节点&#xff09;形成树的一条路径&#xff0c;最长路径的长度为树的深度。 例如&a…

Biotin-PEG-MAL,Maleimide-PEG-Biotin,生物素聚乙二醇马来酰亚胺

英文名称&#xff1a;Biotin-PEG-MAL&#xff0c;Maleimide-PEG-Biotin 中文名称&#xff1a;生物素聚乙二醇马来酰亚胺 Biotin-PEG-Mal&#xff0c;聚乙二醇化生物素对亲和素或链霉亲和素有很高的亲和力。生物素/亲和素体系在生物分子检测和分离中有着广泛的应用。马来酰亚胺…

Container Station搭建个人网盘Nextcloud(Mariadb)

目录 一、Container Station 二、MariaDB安装 三、phpMyAdmin安装及nextcloud对应数据库配置 &#xff08;一&#xff09;phpMyAdmin安装 &#xff08;二&#xff09;nextcloud对应数据库配置 四、Container Station中部署nextcloud &#xff08;一&#xff09;拉取镜像…

javascript下载文件几种方式,接收后台返回流下载或直接下载文件

目录 1 javascript下载文件7中方式 1.1 window.location.href下载 1.2 window.location下载 1.3 iframe下载 1.4 form表单的形式下载 1.5 a标签的方式下载 1.6 ajax方式后台返回文件流下载 1.7 axios方法后台返回流方式下载 2.完整源码 1 javascript下载文件7中方式 1…

Discrete Optimization课程笔记(4)—前沿与工具

目录 1.大规模邻域搜索(Large Neighborhood Search) Case1: 带时间窗的非对称TSP(Asymmetric TSP with Time Windows) 2.列生成算法(Column Generation) Case2: Cutting Stock 3.优化工具汇总 1.大规模邻域搜索(Large Neighborhood Search) 大规模邻域搜索是局部搜索和CP…

linux共享内存的使用

共享内存可以由多个程序同时访问的内存&#xff0c;能够避免进程间通信过程中的冗余数据拷贝&#xff0c;是IPC中最快的一种,特别适合用来作大块数据的传输。共享内存可以映射到不同的进程空间&#xff0c;这些进程间的数据传递就不再涉及内核。这个过程其实是把同一块物理内存…