Spring Cloud全解析:熔断之Hystrix线程隔离导致的问题
Hystrix线程隔离
在微服务框架中,可能一个服务需要调用多个微服务,在tomcat中运行时,tomcat只是分配了100个线程,由于多个服务之间调用的时间消耗过长,可能会导致线程耗尽,而在Hystrix中存在线程隔离,对于每个微服务分配一个线程池,访问某个微服务时就从对应的线程池中取线程,如果对应线程池中的线程都用光了,那么就认为该服务不可用了,如果在需要请求该微服务,则直接返回
那么这个线程池是存在于哪里呢?
- [ ]
既然Hystrix的Command都是在线程池中执行的,就会遇到当前的RequestContextHolder获取不到RequestAttributes,没办法,跨线程了呀(RequestContextHolder中使用了ThreadLocal),这怎么解决呢?Hystrix中提供了一个HystrixConcurrencyStrategy类,HystrixConcurrencyStrategy提供了一套默认的并发策略实现。我们可以根据我们自己不同需求通过装饰去扩展它。如每次执行HystrixCommand的时候都会去调用wrapCallable(Callable) 方法,这里我们就可以通过装饰Callable使它提供一些额外的功能(如ThreadLocal上下文传递)
public class FeignHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy
{private static final Logger log;private HystrixConcurrencyStrategy delegate;public FeignHystrixConcurrencyStrategy() {try {this.delegate = HystrixPlugins.getInstance().getConcurrencyStrategy();if (this.delegate instanceof FeignHystrixConcurrencyStrategy) {return;}HystrixCommandExecutionHook commandExecutionHook = HystrixPlugins.getInstance().getCommandExecutionHook();HystrixEventNotifier eventNotifier = HystrixPlugins.getInstance().getEventNotifier();HystrixMetricsPublisher metricsPublisher = HystrixPlugins.getInstance().getMetricsPublisher();HystrixPropertiesStrategy propertiesStrategy = HystrixPlugins.getInstance().getPropertiesStrategy();HystrixPlugins.reset();// 注册并发策略HystrixPlugins.getInstance().registerConcurrencyStrategy(this);HystrixPlugins.getInstance().registerCommandExecutionHook(commandExecutionHook);HystrixPlugins.getInstance().registerEventNotifier(eventNotifier);HystrixPlugins.getInstance().registerMetricsPublisher(metricsPublisher);HystrixPlugins.getInstance().registerPropertiesStrategy(propertiesStrategy);}catch (Exception e) {log.error("Failed to register Sleuth Hystrix Concurrency Strategy", e);}}// 这个时候还在主线程了,所以通过RequestContextHolder.getRequestAttributes()是能拿到上下文的拿到后hold住,等到run执行的时候再绑定即可public <T> Callable<T> wrapCallable( Callable<T> callable) {// 获取当前请求的requestAttributesRequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();return new WrappedCallable<T>(callable, requestAttributes);}public ThreadPoolExecutor getThreadPool( HystrixThreadPoolKey threadPoolKey, HystrixProperty<Integer> corePoolSize, HystrixProperty<Integer> maximumPoolSize, HystrixProperty<Integer> keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {return this.delegate.getThreadPool(threadPoolKey, corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);}public ThreadPoolExecutor getThreadPool( HystrixThreadPoolKey threadPoolKey, HystrixThreadPoolProperties threadPoolProperties) {return this.delegate.getThreadPool(threadPoolKey, threadPoolProperties);}public BlockingQueue<Runnable> getBlockingQueue( int maxQueueSize) {return this.delegate.getBlockingQueue(maxQueueSize);}public <T> HystrixRequestVariable<T> getRequestVariable( HystrixRequestVariableLifecycle<T> rv) {return this.delegate.getRequestVariable(rv);}class WrappedCallable<T> implements Callable<T>{private final Callable<T> target;private final RequestAttributes requestAttributes;public WrappedCallable( Callable<T> target, RequestAttributes requestAttributes) {this.target = target;this.requestAttributes = requestAttributes;}@Overridepublic T call() throws Exception {try {// 执行之前绑定上下文,执行完成后释放RequestContextHolder.setRequestAttributes(this.requestAttributes);return this.target.call();}finally {RequestContextHolder.resetRequestAttributes();}}}
}
这时候大家就奇怪了,为什么在wrapCallable方法中可以获取到当前请求呢,来看源码是怎么调用HystrixConcurrencyStrategy的
public class HystrixContextRunnable implements Runnable {private final Callable<Void> actual;// 父线程的上下文private final HystrixRequestContext parentThreadState;public HystrixContextRunnable(Runnable actual) {this(HystrixPlugins.getInstance().getConcurrencyStrategy(), actual);}public HystrixContextRunnable(HystrixConcurrencyStrategy concurrencyStrategy, final Runnable actual) {// 实例化HystrixContextRunnable的时候去调用的concurrencyStrategy.wrapCallable,此时还没有切换线程呢this.actual = concurrencyStrategy.wrapCallable(new Callable<Void>() {@Overridepublic Void call() throws Exception {actual.run();return null;}});this.parentThreadState = HystrixRequestContext.getContextForCurrentThread();}@Overridepublic void run() {HystrixRequestContext existingState = HystrixRequestContext.getContextForCurrentThread();try {// set the state of this thread to that of its parentHystrixRequestContext.setContextOnCurrentThread(parentThreadState);// execute actual Callable with the state of the parenttry {actual.call();} catch (Exception e) {throw new RuntimeException(e);}} finally {// restore this thread back to its original stateHystrixRequestContext.setContextOnCurrentThread(existingState);}}}
参考文献
- Hystrix线程隔离导致的问题
相关文章:
Spring Cloud全解析:熔断之Hystrix线程隔离导致的问题
Hystrix线程隔离 在微服务框架中,可能一个服务需要调用多个微服务,在tomcat中运行时,tomcat只是分配了100个线程,由于多个服务之间调用的时间消耗过长,可能会导致线程耗尽,而在Hystrix中存在线程隔离&…...

网络编程项目(云词典项目)
目录 一、功能要求 服务器 用户客户端 二、演示效果 1.登录、注册功能 2. 查单词功能 3.查看历史纪录功能 三、项目代码 1.头文件 2.服务器 3.用户端 一、功能要求 仿照云词典的原理,实现云词典功能,用户可以查询输入的单词的英文解释&…...
Java Spring Boot 项目中的密码加密与验证开发案例手册
本手册主要针对Java项目中的账号密码加密与验证进行详细的步骤讲解和代码示例。适用于开发登录认证、用户管理等功能的场景。文档包含工具类的创建、数据库配置、服务层和控制器层的集成等常见操作。 1. 常用加密操作 在实现安全的登录功能时,密码加密与验证是不可…...

VueSax-解决Vue3报错问题,并支持typescript
以下为坑点 根据官方提示,本人在vue3typescript的项目中添加了vuesax的组件依赖 根据正常的导入依赖思路编写代码,发现typescript一直报 查询vuesax的目录文件发现存在ts文件,于是乎觉得是自己的问题,就查阅gpt与网上资料&#x…...

回归预测 | Matlab基于贝叶斯算法优化XGBoost(BO-XGBoost/Bayes-XGBoost)的数据回归预测+交叉验证
回归预测 | Matlab基于贝叶斯算法优化XGBoost(BO-XGBoost/Bayes-XGBoost)的数据回归预测交叉验证 目录 回归预测 | Matlab基于贝叶斯算法优化XGBoost(BO-XGBoost/Bayes-XGBoost)的数据回归预测交叉验证效果一览基本介绍程序设计参考资料 效果一览 基本介绍 Matlab实现基于贝叶…...

[数据集][目标检测]电动车入梯进电梯电单车入梯检测数据集VOC+YOLO格式7106张3类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):7106 标注数量(xml文件个数):7106 标注数量(txt文件个数):7106 标注…...
大数常用API
package API;public class BigNum {//如果普通的long和double的精度不足以满足要求,那么可以使用java.math包中的两个类//BigInteger和BigDecimal//前者实现任意精度的整数运算,后者实现任意精度的浮点数运算//BigInteger add(BigInteger other)//BigInt…...

Gartner发布ASCA自动化安全控制评估创新洞察:三年后40%的综合安全厂商都将提供ASCA功能
复杂的安全控制网络、技能差距和快速变化的攻击技术使维持技术安全控制的最佳配置的问题更加复杂。安全和风险管理领导者可以通过自动化安全控制评估来改善他们的安全状况。 主要发现 技术安全控制配置错误是与安全漏洞相关的长期问题。薄弱的安全默认值、配置漂移、为减少误报…...

使用lspci命令获取加速卡型号
文章目录 前言一、lspci -nn 获取具体厂商及设备ID二、使用步骤三、使用3080Ti再查询一下 前言 新到的实验机器和加速卡,安装好之后发现lspci命令没有显示型号,这里记录下使用 Vendor ID和Device ID 通过网页查询获取加速卡具体型号的过程。 一、lspci …...

php代码实例强制下载文件代码例子
php代码实例强制下载文件代码例子 $filename $_GET[file]; //Get the fileid from the URL // Query the file ID $query sprintf("SELECT * FROM tableName WHERE id %s",mysql_real_escape_string($filename)); $sql mysql_query($query); if(mysql_num_rows…...

Opencv中的直方图(3)直方图比较函数compareHist()的使用
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 比较两个直方图。 函数 cv::compareHist 使用指定的方法比较两个密集或两个稀疏直方图。 该函数返回 d ( H 1 , H 2 ) d(H_1, H_2) d(H1,H2…...
压力测试(内存、磁盘、网络、cpu)
压力测试 1. 内存压力测试工具stressmemtester 2. 磁盘压力测试工具fio (Flexible I/O Tester)dd (Data Duplicator) 3. 网络压力测试工具iperf3speedtest-cli 4. CPU压力测试工具stress-ng 为了满足更详细的需求,以下是针对内存、磁盘和网络压力测试工具的更深入介…...

ArcGIS JSAPI 高级教程 - ArcGIS Maps SDK for JavaScript - 原生代码实现动态扩散效果
ArcGIS JSAPI 高级教程 - ArcGIS Maps SDK for JavaScript - 原生代码实现动态扩散效果 核心代码完整代码:在线示例 ArcGIS Maps SDK for JavaScript 从 4.29 开始增加 RenderNode 类,可以添加数据以及操作 FBO(ManagedFBO)&#…...

Java 设计模式-代理模式
目录 概述 一. 什么是代理模式 1. 举例说明 二. 代理模式作用 1. 保护代理 2. 增强功能 3. 代理交互 4. 远程代理: 三. 代理模式3个角色 四. 静态代理 1. 代码示例: 五. JDK动态代理 1. 代码示例: 六. CGLIB 动态代理 1.代码示…...
CTF靶场之BUUCTF介绍
最后开始关注CTF,我们先了解一下什么CTF:CTF(Capture The Flag)中文一般译作夺旗赛,在网络安全领域中指的是网络安全技术人员之间进行技术竞技的一种比赛形式,最后以夺取FLAG为成功。 从网上找了一个免费的靶场——BUUCTF…...

学会分析问题,画出分析图,解释问题过程,找出规律 ;整数数组分为左右2个部分,左边位奇数右边偶数
// 整数数组左边是奇数右边是偶数.cpp : Defines the entry point for the console application. //#include "stdafx.h" #include<stdio.h> void swap(int& a,int& b) {int tempa;ab;btemp; } int main(int argc, char* argv[]) {int a[7]{1,2,3,4,5,…...
数学基础 -- 线性代数正交多项式之勒让德多项式展开推导
勒让德多项式展开的详细过程 勒让德多项式是一类在区间 [ − 1 , 1 ] [-1, 1] [−1,1] 上正交的多项式,可以用来逼近函数。我们可以将一个函数表示为勒让德多项式的线性组合。以下是如何推导勒让德多项式展开系数 a n a_n an 的详细过程。 1. 勒让德展开的基本…...

Redis实战宝典:从主从模式、哨兵模式、集群模式一步步理解Redis集群
目录标题 Redis 集群的三种模式主从复制主从复制概念主从复制原理主从复制优缺点 哨兵集群哨兵概念哨兵功能下线判断主库选举故障转移哨兵模式优缺点 Cluser 集群Redis 集群的数据分片 Redis 集群的三种模式 在生产环境中,我们使用 Redis 通常采用集群模式…...

828华为云征文|华为云Flexus X搭建借贷管理系统、二次开发借贷小程序 前端源码uniapp
在华为云828 B2B企业节的盛宴中,Flexus X实例以其卓越的算力性能和灵活的资源配置脱颖而出。对于追求极致性能、渴望在借贷管理、电商交易等场景中脱颖而出的您来说,Flexus X无疑是最佳拍档。搭载创新加速引擎,让您的自建MySQL、Redis、Nginx…...

网站安全需求分析与安全保护工程
网站安全威胁与需求分析 网站安全概念 网站:是基于B/S技术架构的综合信息服务平台,主要提供网页信息及业务后台对外接口服务。 网站安全性: 机密性:网站信息及相关数据不被授权查看或泄露完整性:网站信息及数据不能…...

wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...