Spring Cloud Netflix微服务组件-Hystrix
目录
Hystrix的主要功能
传统容错手段
超时机制
应用容错三板斧
超时机制
舱壁隔离
熔断降级
侵入式Command用法
改进版一:ribbon与hystrix组合
改进版二:feign与hystrix组合
Hystrix三态转换图
源码分析
流程图
核心逻辑流程图
核心实现流程图
入口
HystrixCircuitBerakerConfiguration
如何做功能增强?
@HystrixCommand注解的切面逻辑
流程图
线程池隔离原理
熔断器源码
滑动时间窗口
Hystrix的主要功能
- 线程池隔离、
- 熔断降级、
- 超时降级、
- 宕机降级
传统容错手段
超时机制
是设置RestTemplate的连接超时和读取超时,这是我们在没有使用hytrix这些辅助的分布式工具时的做法

全局异常处理器
控制器中,捕获超时异常,封装成统一的自定义异常并再次抛出,让全局异常处理器来进行处理

上面这种,就是传统的容错的处理套路
应用容错三板斧
超时机制
以前没有hytrix的时候,就是直接给RestTemplate设置一个超时时间,RestTemplate调用超时时会抛出TimeoutException,然后我们直接catch到此异常,就直接把同步阻塞的调用线程掐死

舱壁隔离
说白了就是资源隔离,比如线程池隔离

熔断降级

当一段时间内失败次数达到一定阈值,那么熔断器就会打开,此时主业务线程就不会再去调用真正的远程的业务方法,而是直接调用本地早已写好的“降级方法”,返回一个可预知的结果。也就是说:熔断是结果,降级是处理的手段

侵入式Command用法
我们只会下单、支付、调库存等核心高频接口,才需要进行降级,才需要自己在本地写降级方法

这样当前端看到返回的订单的订单号为-1时,就可以给客户展示一个友好的页面,比如当前系统开了小差之类的

原始的hytrix API处理熔断降级时,就需要这样的强侵入式写法
改进版一:ribbon与hystrix组合


这里可以配置线程池
改进版二:feign与hystrix组合
feign调用时,通过hystrix进行降级



Hystrix的默认配置跳闸阈值

上面就是可能会发生降级的三种情况,分别是:宕机降级、超时降级、异常降级

生产上上面的配置一般不动,使用默认的配置值
Hystrix三态转换图

- 熔断时间窗口结束后,熔断器状态就从打开转换到半开状态,此时会放过一条请求去请求真正的远程业务方法,如果此次调用成功,则熔断器状态就转成关闭状态,如果此次调用任失败,那么熔断器就又会回到打开状态
- 什么叫调用失败?客户端去调用服务端接口API,服务端抛了异常并且没有catch直接抛了出来、服务器宕机、服务端接口业务执行耗时太多导致客户端等待接口返回超时
- 半开状态存在的意义就是为了,让熔断器有机会回到关闭状态(也就是回到能正常去远程调用的状态)
这个就是工作中需要配置的ribbon的超时时间,配置了ribbon的超时时间,那么restTemplate也自动跟随ribbon的超时时间了

这些参数的设置,就供学习,平时生产大多使用默认参数
如何关闭hystrix对feign的支持


这里需要hystrix的超时时间需要设置为6000
生产上需要:
hystrix的超时时间 > (本次调用次数 1 + 出现异常时对当前实例的重试次数 1 + 切换实例后的重试次数 1) * ribbon的超时时间 = 3 * ribbon的超时时间
因为hystrix要保证所有的ribbon调用重试都结束后,hystrix再去插断主线程的调用并给主线程返回降级结果


第89行,把总体的熔断机制的打开
第92行,可以开始选择某一个方法关闭熔断机制(剩下的,就是局部开启的)
注意上面参数赋值用等号=
源码分析
流程图
核心逻辑流程图

核心实现流程图

入口

通过框架的启动注解开始,实际上这个注解内部就是通过@Import注解,去加载spring.factories中以EnableCircuitBreaker为key的“普通配置类”


这个ImportSelector的作用,就是去找Netflix-core.jar下的spring.factories中以EnableCircuitBreaker为key的键值对,将该key对应的值为一个普通配置类HystrixCircuitBerakerConfiguration,将它注入到ioc容器中来

- 因为Springboot默认的自动配置类读取功能,仅仅只是读取所有jar包下spring.factories中以EnableAutoConfigurationr为key的“自动配置类”
- 各个第三方组件自定义的一些key下所属的“普通配置类”,Springboot是不负责读取的,需要各个第三方组件自己开发针对该key的加载功能
- 普通配置类以XxxxxConfiguration命名,自动配置类以XxxxxAutoConfiguration命名

业务系统首先引入这个starter-netflix-hystrix,这个starter相当于一个聚合器,内部聚合了很多别的功能jar包
这些带有spring-cloud-开头的,就是spring cloud官方为了整合Netflix hystrix组件而开发的自动装配包

优先看与核心功能相关的配置类,比如这里就优先看HystrixCircuitBreakerConfiguration类,像这种HystrixSecurityAutoConfiguration一看就是与安全有关的,非主功能,我们就先不看,这些都是看源码的技巧

HystrixCircuitBerakerConfiguration

如何做功能增强?
- 无非就是用代理AOP,横切拦截
- 或者加待增强对象所拥有的拦截器链中加一个拦截器/过滤器
啊
@HystrixCommand注解的切面逻辑
这一段切面逻辑,也就是每一个被@HystrixCommand注解修饰的方法,在被调起之前,都会先走一遍这个切面增强逻辑。而这一段切面增强逻辑,实际上也就是Hystrix熔断器起作用的逻辑

第90行,同时会拦截@HystrixCommand,还有合并请求的@HystrixCollapser

第96行,会创建一个HystrixInvokable,如下是第96行的create()逻辑:

GenericCommand命令模式对象中有两个核心方法,一个就是run()也就是正常的业务逻辑方法,另一个就是getFallback()也就是降级方法,getFallback()内部会通过反射调用@HystrixCommand中配置的fallBackMethod方法
从这里也知道,返回的HystrixInvokable,实际上就是一个GenericCommand

截止以上的流程图
CommandExecutor#execute()



HystrixCommand#execute()

queue()返回一个Future凭证,从这里开始就是一堆的响应式变成了,各种定义监听与事件响应执行来串起整个执行流程

上述流程对应的流程图

响应式编程的定义语法(rxJava响应式编程框架,手机上用的比较多)响应式编程说白了就是一堆的观察者模式,zookeeper里面的节点内容变化也会触发监听器执行,这都是观察者模式

总体原理就是:Observable是被观察者,Observer是观察者,当被观察者发生变化时就会回调观察者

这里就把34行就当做定义了一个观察者,45行就定义了一个被观察者


这里把观察者,注册绑定到被观察者上,以后被观察者发生不同事件,就会回调不同的观察者的call()方法
这里就是被@HystrixCommand注解修饰的方法,在发起一次调用时,如果调用的方法正常返回

这里就出现了一个核心观察者applyHystrixSemantics()
applyHystrixSemantics()
这里就开始最核心的一个观察者的逻辑



线程隔离有两种隔离模式:
- 一种是信号量的隔离模式,信号量计数器满了以后也会走降级逻辑
- 一种是线程池的隔离模式,线程池满了以后也会走降级逻辑

熔断器可以强制配置为关闭,但是这里代码写的有点难理解,与正常思维判断逻辑是个反的
上上图的557行,最后就会调用到降级逻辑

getFallBack()就会在内部找到@HystrixCommand中配置的fallBackMethod方法,并执行这个fallBackMethod方法方法(最终,就是通过方法名,通过反射来调用到fallBackMethod方法的)
正常的线程池隔离执行的逻辑

注意534行


getUserExecutionObservable()方法中就有监听回调方法,回调方法内部就会调用GenericCommand的run()


上述总体流程图:

线程池隔离原理

大体流程:用户在调用findById()方法时,hystrix写的AOP切面类会拦截这个注解,拦截这个注解后会初始化一个GenericCommand命令,在初始化这个GenericCommand命令内部,就会通过这些线程池的配置,来初始化该命令特有的执行线程池

上上图@HystrixCommand注解种鸽所有信息,默认就会被保存在这个元信息MetaHolder中去,spring的代码都是很统一的,这种注解的元数据一般都是用MetaXxxxx来保存的 。这里就通过注解的元信息来构造了一个GenericCommand命令。GenericCommand是AbstractCommand的子类





以后线程池隔离执行时,就是把任务丢进这个threadPool中去执行的
针对线程池本身也有缓存

所以,这里就实现了有多少key就会初始化出来多少个线程池,也就实现了通过key的不同来实现不同粒度的隔离
如果有多个业务方法配置了相同的key,那么也就实现了多个hystrix方法公用了同一个线程池


利用线程池缓存的技术,实现多个用户方法公用同一个线程池的目的,只需要多个方法,配置相同的commandKey和threadPoolKey

熔断器源码

滑动时间窗口



numbuckets就是为了调整时间的统计粒度,统计粒度越细则熔断器对于网络堵塞等异常状态的感应就更加灵敏
滑动窗口触发熔断的最小请求数,这个是整个时间窗口内的,这是一种兜底策略



上图画反了,下图是对的

对应源码如下:

每次请求,都会走上面的判断逻辑

每次请求调用成功没有抛异常,就会调用这个回调方法,这个回调方法内部就会调用断路器进行调用数据上报

206行是上报本次调用数据
相关文章:
Spring Cloud Netflix微服务组件-Hystrix
目录 Hystrix的主要功能 传统容错手段 超时机制 应用容错三板斧 超时机制 舱壁隔离 熔断降级 侵入式Command用法 改进版一:ribbon与hystrix组合 改进版二:feign与hystrix组合 Hystrix三态转换图 源码分析 流程图 核心逻辑流程图 核心实现…...
【6】Spring Boot 3 集成组件:knift4j+springdoc+swagger3
目录 【6】Spring Boot 3 集成组件:knift4jspringdocswagger3OpenApi规范SpringFox Swagger3SpringFox工具(不推荐) Springdoc(推荐)从SpringFox迁移引入依赖配置jAVA Config 配置扩展配置:spring securit…...
从零搭建微服务架构:Spring Boot与Nacos完美整合
🎏:你只管努力,剩下的交给时间 🏠 :小破站 从零搭建微服务架构:Spring Boot与Nacos完美整合 前言第一:服务注册与发现第二:配置中心第三:报错问题解决第四:什…...
原来你不会找资源,三个宝藏白嫖书籍网站,阅读改变生活(一)
[无名图书] - 探索无尽的书海 致力于为你打开一扇通往无限知识和无穷想象的大门。从畅销小说到学术专著,书库涵盖了各个领域,满足了各种阅读胃口。无论你是文学爱好者、学术追求者还是正在寻找新奇刺激的冒险者,这都是你不可错过的阅读伴侣。…...
linux rm文件后空间不释放怎么处理
如题,rm文件后,使用df -h看可用空间,并未增加,这是怎么回事?原来,是有进程在访问这个文件,使用“lsof | grep delete”找到进程并kill掉,此时再看可用空间,便增加了。 我…...
克鲁斯卡尔算法(C++)
目录 克鲁斯卡尔算法 编辑代码: 结果: 克鲁斯卡尔算法 克鲁斯卡尔算法是一种用于求解最小生成树的算法。最小生成树是指一棵包含了所有节点的连通图,并且边的权值之和最小。 克鲁斯卡尔算法的基本思想是,每次选择图中最小的…...
【Shell脚本 4】测试用
#!/usr/bin/env bash # --------------------------------------------------------------------------------- # 控制台颜色 BLACK"\033[1;30m" RED"\033[1;31m" GREEN"\033[1;32m" YELLOW"\033[1;33m" BLUE"\033[1;34m"…...
DC电源模块对效率有什么要求?
BOSHIDA DC电源模块对效率有什么要求? DC电源模块是现代科技中非常重要的组成部分,它是将交流电转换为直流电的装置,可以提供稳定的电源给各种设备和系统使用。效率是DC电源模块的一个关键性能指标,直接影响着模块的整体性能和效…...
Linux在线安装MySQL8.0.24安装、MySQL数据备份和恢复
一、 Linux在线安装MySQL8.0.24 如果机器上已经有MySQL5.7版本需要先卸载 首先,需要停止MySQL服务。可以通过以下命令来停止服务: sudo systemctl stop mysqld接下来,我们需要卸载MySQL5.7。可以通过以下命令来卸载: sudo yum…...
【python】OpenCV—Rectangle, Circle, Selective Search(1.2)
文章目录 1 画框画圈1.1 画矩形框1.2 画圆 / 点1.3 椭圆 2 Selective Search3 Resize 1 画框画圈 1.1 画矩形框 # Copy the image img_rgb_copy img_rgb.copy()# Draw a rectangle cv2.rectangle(img_rgb_copy, pt1 (405, 90), pt2 (740, 510),color (255, 0, 0), thickne…...
MongoDB是一个NoSQL数据库,有着多种不同的命令和操作。以下是一些常见的MongoDB命令:
show dbs:列出所有数据库use db_name:切换到指定的数据库db.dropDatabase():删除当前数据库db.createCollection("collection_name"):创建集合db.collection_name.insert(document):向指定集合插入数据db.co…...
网络运维Day19
文章目录 环境准备数据备份为什么要备份什么是备份备份到哪里什么时候备份如何备份 完整备份物理备份逻辑备份测试恢复所有库 构建MySQL服务xtrabackup完全备份与恢复完全备份完全恢复增量备份增量恢复 总结 环境准备 IP地址采用自动分配,以自己的为准 可以将之前的…...
颜色标记txt和多根走线【Cadance进阶】
文章目录 前言颜色标记txt多根走线 前言 今天来介绍个基础操作中不常见的,但是非常实用的技巧。第一个是颜色标记,它是与text文件结合,根据text文件中的网络来染色标记的,致力于找出那些特定的走线,或者是查询出现问题…...
你是想被ChatGPT改变,还是改变软件开发的未来?丨IDCF
人工智能技术的发展,正在深刻地改变着我们的生活和工作方式。在软件工程领域,ChatGPT作为一种新兴的人工智能技术,正在逐渐地被应用到软件开发的各个环节中。那么,ChatGPT对每个人的影响是什么呢? 一、对软件开发人员…...
Homography详解在MVSNet中的应用
Homography(单应性变换)是计算机视觉中的一个重要概念,用于描述两个平面之间的透视关系。在图像处理和计算机视觉中,Homography通常表示两个平面之间的投影关系,这种关系可以通过一个3x3的矩阵来表示。 在数学上&…...
linux parted给磁盘分区
概述 通常我们用的比较多的分区工具是fdisk命令,但由于fdisk只支持MBR分区,MBR分区表最大支撑2T的磁盘,所以无法划分大于2T的分区。而parted工具可以划分单个分区大于2T的GPT格式的分区,也可以划分普通的MBR分区。 1.查看磁盘大小…...
大数据毕业设计选题推荐-机房信息大数据平台-Hadoop-Spark-Hive
✨作者主页:IT研究室✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…...
使用 PYTORCH 进行图像风格迁移
一、介绍 本教程介绍如何实现 由 Leon A. Gatys、Alexander S. Ecker 和 Matthias Bethge 开发的神经风格算法。神经风格或神经传输允许您拍摄图像并以新的艺术风格再现它。该算法采用三幅图像,即输入图像、内容图像和风格图像,并将输入更改为类似于内容…...
vscode使用flake8设置单行最长字符限制设置失败的问题
vscode使用flake8设置单行最长字符限制设置失败的问题 问题描述解决方案 问题描述 如图所示,使用flake8单行字数过长,就会有有红色底的波浪线 一般情况下很多教程都会让你在setting.json里面设置 但是我打开我的setting.json,发现我已经进…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...
视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...
第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...
LLMs 系列实操科普(1)
写在前面: 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容,原视频时长 ~130 分钟,以实操演示主流的一些 LLMs 的使用,由于涉及到实操,实际上并不适合以文字整理,但还是决定尽量整理一份笔…...
Web后端基础(基础知识)
BS架构:Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端。 优点:维护方便缺点:体验一般 CS架构:Client/Server,客户端/服务器架构模式。需要单独…...
MySQL:分区的基本使用
目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区(Partitioning)是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分(分区)可以独立存储、管理和优化,…...
