hystrix线程池隔离的原理与验证

2023-11-03

引子

幸福很简单:

今天项目半年规划被通过,终于可以早点下班。先坐公交,全程开着灯,买了了几天的书竟然有时间看了。半小时后,公交到站,换乘大巴车。车还等着上人的功夫,有昏暗的灯光,可以继续看会儿书。过会儿车跑起来了,灯关了。我合上书,头靠着车窗,眼睛看着窗外,脑子想着怎么把书里的东西用到工作中进行知行合一。想着想着出了神,突然听到报我们小区的名字,赶紧下了车,刚好没坐过站。

回家一看,那个声称今天会下班很晚的人果然比我还晚。边洗漱边想着上周末,和小鲜肉一起看了动画片。小鲜肉非要我买培根。因为他想像动画片里一样用两个荷包蛋做眼睛,培根做嘴巴。于是晚上睡觉的时候,我下单买了培根,早上7点快递送了来。我就和小鲜肉一起做早餐。他说想吃糖口味的蛋,于是我们改良了一下把荷包蛋眼睛变成摊鸡蛋大脸。本来小鲜肉说只要一片培根。我想一包都打开了,干脆一起煎了。结果因为是自己动手,小鲜肉只好多吃,结果吃培根吃的一天都感觉油腻。想着这周,一包培根要分到一天三顿里,加上配菜,和小鲜肉一起做出三种花样来。关键是小鲜肉到周末比我还忙,8点开始跆拳道,一天各种兴趣班。他想自己做早餐得早起。

洗漱完,吹完头发。看看洗澡水又烧的差不多了。这次终于轮到我发那条消息:“洗澡水够了”。然后拔掉烧水的电源确保安全。竟然有时间贴上面膜再看会书,满足。

原来幸福就是:其实很忙,但是能挤出点时间干点自己的事情,提升提升自己。

hystrix隔离原理

hystrix可以完成隔离、限流、熔断、降级这些常用保护功能。这四个功能可以这么来理解:

hystrix的隔离分为线程池隔离和信号量隔离。

信号量隔离原理

信号量隔离就是hystrix的限流功能。虽然名字叫隔离,实际上它是通过信号量来实现的。而信号量说白了就是个计数器。计数器计算达到设定的阈值,直接就做异常处理。

ratelimiter的令牌桶算法和漏桶算法,都是直接对请求量来计数。只是令牌桶算法可以将前面一段时间没有用掉的请求量允许余额拿过继续用。而漏桶算法一段时间就允许这么多,前面没用掉的也不能用了。

而hystrix信号量隔离限制的是tomcat等Web容器线程数,一段时间仅仅能支持这么多。多余的请求再来请求线程资源,就被拒绝了。所以是一种“曲径通幽”的限流方式。因为实际是通过隔离了部分容器线程资源,也算是一种隔离方式。

线程池隔离原理

信号量隔离只是起了个限制作用,它的保护能力有限:如果下游服务有问题,长时间不返回结果。本身信号量隔离对这个单个请求是起不到任何作用的。它只能限制这样的请求太多了就拒绝,不让整个服务挂。

为了解决这个问题,hystrix又产生了线程池隔离。这种隔离方式是通过引入额外线程的方式。对原来的web容器线程做管理控制:如果一个线程超时未返回,则熔断。既然引入额外的线程就涉及线程池管理、线程的上下文切换这些额外的开销。所以相比信号量隔离,线程池隔离成本更高。

熔断原理

隔离不但可以做保护,还可以做统计:成功了多少失败了多少。既然有统计数据了,它就可以进一步处理:失败太多了,说明现在有问题,执行完了再发现失败太浪费资源,干脆就先不让worker线程执行了。过段时间再试试。这就是断路器模式,也就是熔断的原理。

降级原理

任何异常需要熔断的场景,为的都是反正都是错,干脆把这资源省了。直接返回一个预定的错误。这个熔断后返回设定错误的过程就是降级。

资源保护的流程

从上面来看所谓的hystrix的四大功能:限流、隔离、熔断和降级。只是完成了一整个对资源保护的生命周期。来看看对应的BPMN流程图:

信号量隔离的流程

线程池隔离的流程

现在大家请回答我一个问题:我上面说的是对的吗?

hystrix隔离验证

采用淘金式的思维,不要别人说什么都信。网上很多技术博客里说的都是错的。我的文章也有可能是错的,事实上我说的很多东西都带有自己脑补的成分。

既然不确定是否是对的,就要去验证。先验证

1>hystrix隔离确实能限制资源

2>信号量隔离采用的Web容器的线程池,而线程池隔离采用的是自己独立的线程池。

本次验证,Web容器使用的是spring boot内嵌的jetty。代码已经上传github:

https://github.com/xiexiaojing/yuna

信号量隔离验证

隔离hystrix配置

import com.netflix.hystrix.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;


import java.util.concurrent.TimeUnit;


@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class DemoHystrixCommand extends HystrixCommand<String> {
    private static final Logger logger = LoggerFactory.getLogger(DemoHystrixCommand.class);
    private String poolName;


    public DemoHystrixCommand() {
        super(Setter.withGroupKey(
                //服务分组
                HystrixCommandGroupKey.Factory.asKey("DemoGroup"))
                //线程分组
                .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("DemoPool"))
                //线程池配置
                .andThreadPoolPropertiesDefaults(
                        HystrixThreadPoolProperties.Setter()
                                .withCoreSize(2)
                                .withKeepAliveTimeMinutes(5)
                                .withMaxQueueSize(2)
                                .withQueueSizeRejectionThreshold(10))
                //线程池隔离
                .andCommandPropertiesDefaults(
                        HystrixCommandProperties.Setter()
                                .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE)
                )
        );
    }


    @Override
    protected String run() throws Exception {
        logger.info(poolName + ":我伤心我无奈,可是我默默等待");
        TimeUnit.MILLISECONDS.sleep(100);
        return poolName + "-run:缘分就是一生的等待";
    }


    public void setPoolName(String poolName) {
        this.poolName = poolName;
    }
}

调用方



import com.brmayi.yuna.util.DemoHystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;


import javax.annotation.Resource;


@RestController
public class HystrixController {
    @Autowired
    private ApplicationContext applicationContext;


    @GetMapping("/hystrix")
    public String hystrix(String poolName) throws Exception {
        DemoHystrixCommand demoHystrixCommand = applicationContext.getBean(DemoHystrixCommand.class);
        demoHystrixCommand.setPoolName(poolName);
        return demoHystrixCommand.execute();
    }
}

验证

多点几次

多点几次

看日志,日志前缀里Web容器的其他日志线程号和请求hystrix的线程号规则一致,可说明是Web容器的线程。

注意看,不管是倩倩还是萍儿,它们的线程数都没有超过最大线程数

线程池隔离验证

只要将隔离hystrix配置

HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE

改成

HystrixCommandProperties.ExecutionIsolationStrategy.THREAD

重启后重复上面验证步骤

看线程池名变成了隔离hystrix配置的线程名规则!并且不管是倩倩还是萍儿,它们的线程数都没有超过最大线程数。

以上实验说明

1>hystrix隔离确实能限制资源

2>信号量隔离采用的Web容器的线程池,而线程池隔离采用的是自己独立的线程池。

成立。

其他部分限于篇幅,我就不验证了。这里用到了打日志的方法验证线程池情况。如果在生产环境,实际上我们是需要对线程池情况做监控的。可以使用java.lang.management包里的工具注册监控。我们平时使用falcon这样的工具来查看,原理也是先通过java.lang.management包里的工具注册上报信息到服务端采集的。如果自己想查看监控结果,可以用jdk自带的jvisualvm安装一个com-sun-tools-visualvm-modules-mbeans.nbm插件来看。

总结

本篇文章的验证部分很粗糙,限于篇幅,没有把所有需要验证的点覆盖全。想验证我花的hystrix资源保护生命周期的图,至少要结合源码和验证两方面。先当留作业了,有时间我把详细过程补上。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

hystrix线程池隔离的原理与验证 的相关文章

  • V8 如何管理它的堆?

    我知道V8的垃圾收集在工作时 会从GC的root开始追踪 这样无法到达的对象就会被标记然后被清除 我的问题是GC是如何遍历那些对象的 必须有一个数据结构来存储所有可达或不可达的对象 位图 链接表 顺便说一句 JVM 也做同样的事情吗 艾伦秀
  • Spring webflow 应用程序:HTTP 302 暂时移动

    我的 java 应用程序中的每个请求都会生成另外 2 个带有 HTTP 302 错误的请求 例如 如果请求查看名为板 html 这个请求是从首页 html 我收到按以下顺序生成的 3 个请求 POST home html 302 Moved
  • 使用 Java 编程式 HTML 文档生成

    有谁知道如何在 Java 中以编程方式生成 HTMLDocument 对象 而不需要在外部生成字符串 然后使用 HTMLEditorKit read 来解析它 我问的两个原因 首先 我的 HTML 生成例程需要非常快 并且我认为将字符串解析
  • 如何在Spring的applicationContext.xml中指定默认范围来请求范围?

    我想让所有 bean 请求默认作用域 但是 Spring 文档说默认作用域是 Singleton 第 3 4 1 和 3 4 2 节http static springsource org spring docs 2 5 x referen
  • JUnit Eclipse 显示 System.out.print() 的

    我正在使用 JUnit 3 和 Eclipse 3 4 当我运行 JUnit 测试用例时 一切正常并且测试完美完成 唯一的事情是我想查看我正在运行的类的输出 所有类都具有一些输出值的基本 System out print 因此 当我运行测试
  • 如何在 OpenAPI 3.0 中定义字节数组

    我正在将 API 从 Swagger 2 0 迁移到 OpenAPI 3 0 在 DTO 中 我有一个指定为字节数组的字段 Swagger 对 DTO 的定义 Job type object properties body type str
  • 无法从后台服务通过 WiFi 访问互联网

    我将直接介绍我发现的一些事实 数据 如果您遇到 解决了类似的问题 请帮助我 我每 5 分钟向服务器发送一次数据 除非用户在服务器的帮助下手动将其关闭 wakeful broadcast receiver通过一个intent service
  • 业务代表与服务定位器

    Business Delegate 和 Service Locator 之间有什么区别 两者都负责封装查找和创建机制 如果 Business Delegate 使用 Service Locator 来隐藏查找和创建机制 那么 Busines
  • Vertx HttpClient getNow 不工作

    我的 vertx HttpClient 有问题 下面的代码显示使用 vertx 和纯 java 测试 GET Vertx vertx Vertx vertx HttpClientOptions options new HttpClientO
  • Java String.format 向整数添加空格

    我有一小段代码 我不明白输出 此输出向我的字符串格式文本添加空格 我做错了什么吗 public class HelloWorld public static void main String args int a1 540 int a2 4
  • 如何在将数据发送到 Firebase 数据库之前对其进行加密?

    我正在使用 Firebase 实时数据库制作聊天应用程序 我知道 Firebase 非常安全 只要您的规则正确 但我自己可以阅读使用我的应用程序的人的所有聊天记录 我想阻止这种情况 为此我需要一种解密和加密方法 我尝试使用凯撒解密 但失败了
  • 当容器大小更改时,JTable 仅调整选定列的大小

    对于面板内的 JTable 如果面板变大 我如何将额外的空间仅分配给某些列 在我的例子中 分配给最后一列 尽管提供 第 3 4 列和8 将获得额外的空间 我想允许用户手动更改所有列的列大小 我尝试了 table setAutoResizeM
  • java中的比较器链

    正在阅读Oracle 关于接口的 Java 教程 https docs oracle com javase tutorial java IandI createinterface html其中给出了一个例子Card 打牌 我试图理解接口中的
  • 使用 Maven 3 时 Cobertura 代码覆盖率为 0%

    读完这篇文章后 将 Cobertura 与 Maven 3 0 2 一起使用的正确方法是什么 https stackoverflow com questions 6931360 what is the proper way to use c
  • 将字符串中的字符向左移动

    我是 Stack Overflow 的新手 有一道编程课的实验室问题一直困扰着我 该问题要求我们将字符串 s 的元素向左移动 k 次 例如 如果输入是 Hello World 和3 它将输出 lo WorldHel 对于非常大的 k 值 它
  • Scala repl 抛出错误

    当我打字时scala在终端上启动 repl 它会抛出此错误 scala gt init error error while loading AnnotatedElement class file usr lib jvm java 8 ora
  • Android同步onSensorChanged?

    这是我的问题的后续 Android线程可运行性能 https stackoverflow com questions 36395440 android thread runnable performance 我在理解应用程序的同步方法时遇到
  • JDK 7 的快速调试/调试构建

    我正在寻找 JDK 的调试 或者我猜他们称之为快速调试构建 以启用在运行时生成的打印程序集以及查找性能问题时所需的其他诊断 就目前情况而言 我似乎找不到可以直接使用的 现成的 快速调试构建二进制包 有人可以帮我提供下载链接 或者至少提供有关
  • Java泛型类型

    当我有一个界面时 public interface Foo
  • 将隐藏(生物识别)数据附加到 pdf 上的数字签名

    我想知道是否可以使用 iText 我用于签名 或 Java 中的其他工具在 pdf 上添加生物识别数据 我会更好地解释一下 在手写板上签名时 我会收集签名信息 例如笔压 签名速度等 我想将这些信息 java中的变量 与pdf上的签名一起存储

随机推荐

  • ajax实现向购物车添加,jQuery添加到购物车的互动

    插件描述 当用户决定购买某件物品的浮动购物车交互效果 添加到购物车 的过程 我们习惯于不同的模式 这种模式背后的基本思想是以通知用户 项目已添加到购物车 并为他 她提供一个链接来结帐 我们已经尝试过使用默认情况下 隐藏购物车和显示它当用户单
  • 一文玩转 Java 日志数据脱敏

    许多系统为了安全需要对敏感信息 如手机号 邮箱 姓名 身份证号 密码 卡号 住址等 的日志打印要求脱敏后才能输出 本文将结合个人经历及总结分享一种log4j日志脱敏方式 自定义Layout import org apache logging
  • 在vue中使用webpack打包

    1 安装webpack npm install vue 2 vue loader 15 vue template compiler 2 save dev 2 在项目中创建webpack config js 配置 const path req
  • 如何考虑BLL层和DAL层的日志

    DAL层日志 DAL层与数据库交互 日志记录的目的是 1 发生异常时通过日志查找原始信息 便于快速定位原因 2 对于一些复杂的事务可以通过对日志的分析来发现错误的具体位置 BLL层日志 BLL层与UI交互 虽然UI已经对用户输入进行了一些过
  • 创建数据库是列名无效咋办_怎样解决列名无效 - 技术问答 - .Net源码论坛 .net源码,ASP.net

    列名 Class 无效 说明 执行当前 Web 请求期间 出现未处理的异常 请检查堆栈跟踪信息 以了解有关该错误以及代码中导致错误的出处的详细信息 异常详细信息 System Data SqlClient SqlException 列名 C
  • 中小企业如何做好MES管理系统实施建设

    中小企业在生产制造领域面临着诸多挑战 包括提升产品竞争力 规范生产制造等 为了应对这些挑战 越来越多的中小企业开始实施MES生产管理系统 然而 由于企业规模小 资源实力不足等原因 很多企业在实施MES管理系统时存在一定的困难 本文将从认知误
  • Linux for Ubuntu Intellij Idea 免費激活

    注冊碼與方法請點擊這裏 更改hosts方法 sudo gedit etc hosts
  • 【Git基础入门】Git工具的日常基本使用

    Git基础入门 Git工具的日常基本使用 一 git介绍 二 git的四个区域 2 git四个区域名称 2 2 git四个区域工作关系 三 git工作的三种场景 1 场景1 本地目录有代码 2 场景2 本地目录无代码 3 场景3 直接git
  • 设备发现协议SSDP实现

    原理 1 将socket加入239 255 255 250 端口 1900 2 客户端 通过设置setsockopt IPPROTO IP IP ADD MEMBERSHIP属性 可向ssdp组进行组播 3 服务端 通过设置绑定239 25
  • 谷歌&北大扩散模型(Diffusion Model)首篇综述来了!

    本综述 Diffusion Models A Comprehensive Survey of Methods and Applications 来自加州大学 Google Research的Ming Hsuan Yang 北京大学崔斌实验室
  • 透析极大极小搜索算法和α-β剪枝算法(有案例和完整代码)

    文章目录 前言 minimax算法 完整代码 算法思想 代码实现 算法优化 剪枝算法 完整代码 算法思想 代码实现 算法对比 更多案例 结语 前言 先做了一版五子棋的小项目 后面又做了一个功能更强大的中国象棋的项目 但是始终都没有实现一版
  • Java+Aspose.diagram,导出数据到Visio

    背景 java 家谱图导出 主要包括家庭成员图片以及有关系进行连线 项目环境请参考 https download csdn net download weixin 49456013 20085264 或者是参考我关于Aspose相关的文章
  • 使用Eclipse与Pydev开发Python

    http loosky net 1152 html Python的编辑器很多 具体可见 http wiki python org moin PythonEditors 官方的IDLE PythonWin和Eclipse Pydev 是比较值
  • 服务器性能网络指标,什么是网络性能指标 网络性能指标有哪些

    什么是网络性能指标 网络性能指标有哪些 这些一定要考虑的 一 什么是网络性能指标 网络性能指标 是衡量网络性能的指标 包括带宽 时延 带宽时延积 二 网络性能指标有哪些 端到端的网络性能指标包括传输线路指标 网络时延指标和网络设备指标 1
  • 鲸鱼优化算法——使用Python实现

    鲸鱼优化算法 使用Python实现 鲸鱼优化算法是一种新兴的优化算法 它受到鲸鱼集群捕猎行为的启发 该算法具有全局搜索能力和收敛速度快等优点 在多个领域中得到了广泛应用 本文将介绍使用Python实现鲸鱼优化算法 并提供源代码 鲸鱼优化算法
  • ubuntu18.04源码编译pytorch

    上篇文章win10安装pytorch只是安装好了库 但是并不能追踪到pytorch源代码 windows平台下的源码编译太过麻烦 linux系统笔者是安装在虚拟机中 并不能调用宿主机的CUDA和CUDNN 但是还是编译一下CPU版的pyto
  • R语言绘制各式各样的图形

    R语言绘制五个节点的有向图 library igraph g2 lt graph edges c 1 4 1 3 1 2 1 5 2 4 2 3 2 5 n 5 gt set vertex attr color value cadetblu
  • 第17课:生活中的享元模式——颜料很贵必须充分利用

    用程序来模拟生活 从剧情中思考享元模式 享元模式 享元模式的模型抽象 类图 基于框架的实现 模型说明 设计要点 优缺点 应用场景 故事剧情 团队的拓展培训是很多大公司都组织的活动 因为素质拓展培训能将企业培训 团队建设 企业文化融入到有趣的
  • vue项目,浏览器报错:ReferenceError: h is not defined

    Jsx语法 遇到这种错误 检查一下自己data 内有没有类似图片上的代码结构的参数 这种属于jsx语法 也能直接将组件渲染出来 但是在某些特定情景下浏览器控制台会报 ReferenceError h is not defined这个错误 解
  • hystrix线程池隔离的原理与验证

    引子 幸福很简单 今天项目半年规划被通过 终于可以早点下班 先坐公交 全程开着灯 买了了几天的书竟然有时间看了 半小时后 公交到站 换乘大巴车 车还等着上人的功夫 有昏暗的灯光 可以继续看会儿书 过会儿车跑起来了 灯关了 我合上书 头靠着车