分析排查Hystrix熔断降级未能真正生效的问题

2023-11-18

1. 现象

压测无法进入hystrix熔断处理, 检查feign.hystrix.enabled是开启的,hystrix设定的最大并发连接为100,降级最大并发连接为50

hystrix.command.default.execution.isolation.semaphore.maxConcurrentRequests=100

hystrix.command.default.fallback.isolation.semaphore.maxConcurrentRequests=50

理论上连接超过150,就会触发fallback降级处理, 但并发压测线程从100~1500, 都未能触发熔断降级,于是开始了逐步排查之路。

2. 排查

  1. 检查hytrix有无独立配置

    FeignClient是可以支持独立的配置,检查要调用的服务,有无配置configuration

    @FeignClient(name = Constants.SERVICE_NAME,
            fallback = OrderService.HystrixClientOrderService.class,
            configuration = FeignClientWithoutHystrixConfig.class)
    

    如果配置中采用的是Feign.builder(), 是不会走hystrix熔断逻辑:

    public class FeignClientWithoutHystrixConfig {
    
       private final Logger log = LoggerFactory.getLogger(this.getClass());
       @Bean
       public Feign.Builder feignBuilder() {
          return Feign.builder();
       }
    }
    

    再检查有无全局的@Configuration配置, 发现并没有。

  2. 检查hystrix有未真正拦截处理

    原接口存在一大堆业务逻辑, 为便于调试, 简化逻辑,重新抽取为独立的接口,调用测试,

    发现是受到hystrix的控制,通过HystrixInvocationHandler对象进行调用:
    在这里插入图片描述

  3. 检查hystrix有无读到正确的并发数配置

    增加属性配置, 并打印出来, 是配置正确的并发数
    在这里插入图片描述

  4. 检查测试程序的并发是否受限

    到这一步, 问题就变得比较蹊跷, 这时候需要检查测试程序是否能够达到相应的并发数,因为是走的http并非feign方式调用, 这时需要检查httpclient的连接池配置, 发现存在问题:
    在这里插入图片描述
    我们要知道服务的调用关系以及熔断作用的地方:
    在这里插入图片描述

    maxConnPerHost 为 50,限制住了调用应用服务A最大50个连接, 从上游就限制住了并发数是进入不了熔断的,所以需要将maxTotalConn和maxConnPerHost都调大, 要超过hystrix配置的最大并发数。

    这就结束了?并没有,但结果有一些不一样, 应用服务A重启后, 第一次压测, 会有部分连接进入熔断,但再重试几次, 就没有再进入压测, 这又是什么原因, 还得继续摸排。

  5. 减小hystrix并发阈值

    由于服务启动第一次能进入熔断,说明hystrix是有生效的, 这时候尝试将hystrix的并发阈值调小:

    hystrix.command.default.execution.isolation.semaphore.maxConcurrentRequests=50

    效果出来了, 每次调用,都会有部分请求出现熔断, 但为何加大就不行呢, 生产环境肯定不能配置这么小,

    得继续查明具体原因。

  6. hytrix源码增加日志打印

    这时候就有必要深入源码进行跟踪分析了, 找到AbstractCommand关于信号量的判断处理逻辑, 在内部增加日志打印, 观测实时的信号量变化。

在这里插入图片描述
要让日志正常打印, 不要忘记指定日志级别输出
在这里插入图片描述
测试并跟踪输出,发现连续几轮, 信号量最高都是在60左右徘徊, 无论测试程序的并发数是100或1000
在这里插入图片描述

  1. 修改容器undertow的并发接入数限制

    排查一大圈, 可以确定应用服务内部是受到了限制, 导致并发上不去, 那会有什么在hystrix之前对连接做限制呢, 最大的嫌疑就是服务容器了,检查了spring boot启动输出, 采用的是undertow,看下默认的连接数是多少, 查阅其源码:

    private Builder() {
                ioThreads = Math.max(Runtime.getRuntime().availableProcessors(), 2);
                workerThreads = ioThreads * 8;
                long maxMemory = Runtime.getRuntime().maxMemory();
                //smaller than 64mb of ram we use 512b buffers
                if (maxMemory < 64 * 1024 * 1024) {
                    //use 512b buffers
                    directBuffers = false;
                    bufferSize = 512;
                } else if (maxMemory < 128 * 1024 * 1024) {
                    //use 1k buffers
                    directBuffers = true;
                    bufferSize = 1024;
                } else {
                    //use 16k buffers for best performance
                    //as 16k is generally the max amount of data that can be sent in a single write() call
                    directBuffers = true;
                    bufferSize = 1024 * 16;
                }
    
            }
    
    

    可以看到workerThreads就是控制实际工作的线程数, 这里默认是根据CPU核心数来配置的, 如果CPU是8个核心,那么workerThreads工作线程数就是64,这也就意味着,如果每个请求占据1S的处理时间, 那么TPS并发只能是64,这和上面的信号量一直在60左右是初步吻合的,我们修改其数量为256:

    server:
    undertow:
    worker-threads: 256

    再次进行压测, 可以看到信号量上升超过了100阈值,请求被拒绝了: 在这里插入图片描述
    至此, hystrix可以正常生效控制了。

3. 总结

  1. 进行hystrix限流降级配置,要了解其工作原理和各项配置的作用, 便于排查定位。

    如果并发超过阈值hystrix.command.default.execution.isolation.semaphore.maxConcurrentRequests=100,会产生拒绝rejection,并进入降级处理逻辑:

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

    如果进入降级的请求数超过阈值

    hystrix.command.default.fallback.isolation.semaphore.maxConcurrentRequests=50, 则会拒绝产生熔断,熔断恢复要根据时间窗配置的时间确定hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds=20000

  2. 在进行压测时, 一定要确保各个环节的连接没有受限, 无论是测试程序的httpClient,还是应用服务容器的undertow,或是操作系统的tcp连接限制, 都要做好相应的检查。undertow的工作连接配置修改:

    server:
    undertow:
    worker-threads: 256

    如果测试程序是采用feign连接调用,那么需要修改feign的http连接池配置,参数如下:

    feign.httpclient.enabled=true
    feign.httpclient.max-connections=400
    feign.httpclient.max-connections-per-route=200

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

分析排查Hystrix熔断降级未能真正生效的问题 的相关文章

  • 如何在url请求中发送数组

    我的要求如下 我想给出演员姓名 开始日期 结束日期并获取他在该时期出演的所有电影 因此 我的服务请求是这样的 http localhost 8080 MovieDB GetJson name Actor startDate 20120101
  • 如何作为应用程序发布到页面?

    所以 我有一个应用程序 Facebook 应用程序实体 并且我有一个页面 我想使用应用程序通过java代码 通过restfb或任何其他建议 发布到页面 看起来我错过了页面授予应用程序发布权限的阶段 不知道该怎么做 谢谢你们 乌里 您只能 作
  • Spring boot 中特定包的自定义日志文件

    我有一个带有专门操作的java包 专业化是因为它们很少被使用 并且我不想将它们与普通日志记录混合在一起 我知道添加logging file myapplication log会将日志记录重定向到此文件 但有没有办法指定仅从特定包记录到另一个
  • 我需要在 JFileChooser(打开模式)中显示不带扩展名的文件名。如何?

    我在打开模式下使用 JFileChooser 我需要显示不带扩展名的 文件名 字段 如何 我知道文件视图 它删除文件系统文件中的扩展名 但将所选文件中的扩展名保留在 文件名 字段中解释 http saveimg ru show image
  • JavaFX使节点覆盖父节点边框颜色

    我有一个如下所示的节点 仅使用 css 我希望标签覆盖其父边框颜色 因此标签下方的边框颜色部分变得不可见 我用来制作这个边框的CSS代码 fx border color black fx border width 3 fx border r
  • 在java中将字符串日期转换为美国格式

    我有下面的代码 其中日期为字符串类型 我必须将其设置为美国格式 所以下面我已经展示了它 private static final SimpleDateFormat usOutputDate new SimpleDateFormat MM d
  • 无法在 Java 中输出正确的哈希值。怎么了?

    在我的 Android 应用程序中 我有一个 SHA256 哈希值 我必须使用 RIPEMD160 消息摘要算法进一步对其进行哈希值 我可以输出任何字符串的正确 sha256 和ripemd160 哈希值 但是当我尝试使用ripemd160
  • 确定序列化对象的类型

    我需要通过套接字发送消息 从用户到引擎的请求 以及从引擎到用户的响应 所以流程本质上是 serialized request Server lt network gt Client serialized response request r
  • 具有 JPA 持久性的 Spring 状态机 - 存储库使用

    我试图弄清楚如何轻松使用 Spring 状态机 包括使用 JPA 进行持久化 这是我正在处理的问题 不兼容的数据类型 工厂和持久性 在程序的某个时刻 我想使用连接到用户的状态机 有用于此目的的存储库 项目spring statemachin
  • 在带有 Protocol Buffers 的项目中使用 Proguard 有什么特点?

    我有一个使用 Google Protocol Buffers 的项目 一旦我尝试用 ProGuard 对其进行混淆 似乎 protobuf 会导致问题 我将所有自己的类打包成mybuildedclasses jar 谷歌代码被打包成prot
  • 如何在不反编译的情况下更改已编译的.class文件?

    我想更改 class 文件方法 我安装 JD Eclipse Decompiler 并打开 class 文件 我添加了一些代码并保存 class 文件 但是 class 文件没有改变 我不知道如何使用反编译器 如果可能的话 如何在不使用反编
  • 使用单独的线程在java中读取和写入文件

    我创建了两个线程并修改了 run 函数 以便一个线程读取一行 另一个线程将同一行写入新文件 这种情况会发生直到整个文件被复制为止 我遇到的问题是 即使我使用变量来控制线程一一执行 但线程的执行仍然不均匀 即一个线程执行多次 然后控制权转移
  • HTTP 状态 405 - 此 URL java servlet 不支持 HTTP 方法 POST [重复]

    这个问题在这里已经有答案了 我无法使页面正常工作 我有要发布的表单方法和我的 servlet 实现doPost 然而 它不断地向我表明我并不支持POST方法 我只是想做一个简单的网站并将值插入到我的 MySQL 数据库中 type Stat
  • 删除 JFX 中选项卡后面的灰色背景

    So is there any way to remove the gray area behind the tab s 我尝试过用 CSS 来做到这一点 但没有找到方法 要设置 tabpane 标题的背景颜色 请在 CSS 文件中写入 t
  • 使用 PC/SC 读卡器验证 Ultralight EV1

    我在尝试使用 Java 中的 PC SC 读卡器 特别是 ACR1222L 验证 Ultralight EV1 卡时遇到问题 我能够使用 ISO 14443 3 标签的相应 APDU 在不受保护的标签上进行写入和读取 但是 我找不到运行 P
  • 如何制作一个makefile只用于编译一些java文件?

    我有三个java文件 名为A java B java C java A将创建对象B B将创建对象C 但我以前从未构建过makefile 有谁可以帮我构建一个 makefile 来编译这三个 java 文件吗 我应该使用什么工具来制作 mak
  • 升级到 Spring boot 1.4 后服务无法启动

    我刚刚升级了所有 Spring Boot 服务1 3 6 RELEASE to 1 4 0 RELEASE 现在它们都在启动时崩溃 Caused by java lang NoClassDefFoundError org springfra
  • 让 Hibernate 和 SQL Server 与 VARCHAR 和 NVARCHAR 良好配合

    我目前正在大型数据库的某些表中启用 UTF 8 字符 这些表已经是 MS SQL 类型 NVARCHAR 此外 我还有几个使用 VARCHAR 的字段 Hibernate 与 JDBC 驱动程序的交互存在一个众所周知的问题 例如 参见在 h
  • 为什么java.lang.Cloneable不重写java.lang.Object中的clone()方法?

    Java 规范java lang Cloneable接口将自身定义为表示扩展它的任何对象也实现了clone 休眠的方法java lang Object 具体来说 它说 一个类实现了Cloneable接口来指示java lang Object
  • java中void的作用是什么?

    返回类型 方法返回值的数据类型 如果方法不返回值 则返回 void http download oracle com javase tutorial java javaOO methods html http download oracle

随机推荐

  • MATLAB代码显示内存不足的解决方法

    总结了下大家对于运行MATLAB代码 显示内存不足的问题 在网上进行调研 总结如下 一般out of memenry存在以下几种情况 1 变量需要的存储空间超过了可用的内存空间 2 数据需要的存储空间 超过内存中最大的可用连续存储空间 3
  • 最大子列和问题【简单易懂】

    问题 给定N个整数的序列 求函数的最大值 算法一 例如序列为 1 2 3 4 所以子列分别为 1 1 2 1 2 3 1 2 3 4 2 2 3 2 3 4 3 3 4 4 我们要做的就是依次将这些子列的和求出并比较 得出最大子列和 首先将
  • 2020算法设计与分析 官方考前模拟卷 参考答案

    算法设计与分析 样例试题 算法设计与分析总结笔记 注 此试题仅供了解题型 和期末考试试题没有任何直接关系 FBI Warning 这套题难度较大 千万不要坏了心态 xj大佬说要是考试那么难他直播粪坑蝶泳 Power By 王宏志教授 5 分
  • matlab的tfdata函数_matlab 入门基本操作命令与函数

    一 tf 函数 是传递函数的意思 一般学自动控制原理的时候经常用 在s域中 比如你要输入G s 1 s 2 2s 1 就可以在matlab中输入G tf 1 1 2 1 就OK了 不懂的话你可以在command窗口输入help tf 就行了
  • 为什么使用start方法启动Java的Thread线程?

    一 简介 在Java代码当中 当我们需要开启子线程去处理一些任务的时候 往往是调用Thread对象的start方法 这样Thread实例中的Runnable对象的run方法就会在一个新的线程当中执行 创建一个线程 Thread thread
  • 从注意力机制到Vison Transformer

    原视频链接 https www bilibili com video BV1Jh411Y7WQ spm id from 333 788 vd source f04f16dd6fd058b8328c67a3e064abd5 https www
  • 【Zabbix实战之运维篇】Zabbix的客户端自动注册配置

    Zabbix实战之运维篇 Zabbix的客户端自动注册配置 一 自动注册与自动发现介绍 1 自动注册介绍 2 自动发现介绍 3 主动模式与被动模式 二 客户端安装abbix agent2 1 下载zabbix agent2软件包 2 安装z
  • Python 设计真实反弹球算法及原理分析 (使用物理定律)

    文章简单地使用物理定律 编写程序模拟真实世界中的碰撞 在开始正式讲解之前 先看这两个代码 把球掉头 ball speed 0 ball speed 0 ball speed 1 ball speed 1 可以看到 这个代码直接把球的速度反了
  • 某电商数据分析:利用SQL做查询分析

    本文利用MYSQL在数据分析中的作用 将数据导入NAVICAT 对某电商展开数据分析工作 一 理解数据 字段说明 1 orderinfo表 1 orderid 订单编号 2 userid 用户编号 3 isPaid 订单状态 是否已支付 4
  • element ui 树形控件点击

    element 树形控件 点击当前节点 鼠标再离开后 当前节点就是个白色的背景颜色 我试了很多方法都不能完全性解决这个问题 最后是 gt gt gt el tree node focus gt el tree node content ba
  • Java笔试面试总结—try、catch、finally语句中有return 的各类情况

    前言 之前在刷笔试题和面试的时候经常会遇到或者被问到 try catch finally 语法块的执行顺序等问题 今天就抽空整理了一下这个知识点 然后记录下来 正文 本篇文章主要是通过举例的方式来阐述各种情况 我这里根据 try catch
  • 编译SandBoxie-plus自动生成文件脚本

    首先添加moc exe所在目录的PATH环境变量 moc exe MiscHelpers Common CheckableMessageBox h o MiscHelpers Common moc CheckableMessageBox c
  • 【科普】波特率和比特速率的理解

    什么是波特率 单位时间内传输的码元个数称为波特率 单位为 Baud 那码元又是什么呢 码元又称为 符号 即 symbol 维基百科上对码元的解释 持续一段固定时间的通信信道有效状态就是码元 这么解释比较抽象 可以解释码元的物理意义 在通信信
  • win7下exe提示无法正常启动(0xc0000906)

    本人遇见是 avast问题 卸了
  • 【特征工程】特征创建(属性创建)

    特征创建也称属性创建 包括 特征提取 映射数据到新的空间 二次特征 特征构造 1 特征提取 肯定就生成新的特征 2 将数据映射到新的空间 扩维或降维 也会形成性的特征 3 二次特征 通过基础特征构造出新的特征
  • 《Python编程无师自通》读书笔记

    不能越界访问函数内部定义的变量 global不能乱用 啥时候用元组 join连接 小点 但第一次见会觉得蛮有意思 Hangman 10 1的案例蛮有意思的 一搜才发现是十分经典的文字游戏 过程式编程的缺点以及函数式编程和面向对象编程的解决方
  • c++标准异常类的继承实现

    出处来自百度 查来学习之用 AbnomalTest cpp 定义控制台应用程序的入口点 include StdAfx h include
  • Qt中绘制折线

    Qt中绘制折线 基本流程 三要素 场景 图表 序列 创建场景 创建图表 图表添加到场景 创建序列 序列添加到图表 创建坐标轴并设置 坐标轴添加到图表 序列 坐标轴 图表配合 序列设值 1 必要配置 pro文件 QT charts 头文件 i
  • 常见操作String的方法(字符查找,索引查找)

    常见操作String的方法 字符查找 索引查找 在给定的字符串中查找字符或字符串是比较常见的操作 字符串查找分为两种形式 一种是在字符串中获取匹配字符 串 的索引值 另一种是在字符串中获取指定索引位置的字符 根据字符查找indexOf la
  • 分析排查Hystrix熔断降级未能真正生效的问题

    1 现象 压测无法进入hystrix熔断处理 检查feign hystrix enabled是开启的 hystrix设定的最大并发连接为100 降级最大并发连接为50 hystrix command default execution is