Hystrix 简介

Hystrix 是 Netflix 开源的一个限流熔断降级组件,防止依赖服务发生错误后,将调用方的服务拖垮。这里对 Hystrix 本身不做过多介绍。

Hystrix 目前处于维护状态(不再更新),但是还有大量项目对它进行了使用,因此仍然非常重要。

基本用法

在 Hystrix 中,HystrixCommand 是非常重要的一个类,用于对目标服务进行保护。

在 Hystrix 的基本用法中:

  • 首先,我们需要创建一个自定义类 CustomHystrixCommand 来继承 Hystrix 提供的 HystrixCommand 类。
  • 然后,每次调用服务的时候,我们需要创建一个 CustomHystrixCommand 实例,将调用的逻辑封装在该 Command 之内,然后 Hystrix 就会帮我们根据配置,自动对系统进行保护,在适当的时候进行限流、熔断降级的操作。

例如,在 Hystrix 官方文档 中有个很简单的 Hello World 例子:

首先,创建自定义类 CommandHelloWorld

public class CommandHelloWorld extends HystrixCommand<String> {

    private final String name;

    public CommandHelloWorld(String name) {
// 这里是当前 Command 的配置信息
super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
this.name = name;
} @Override
protected String run() {
// a real example would do work like a network call here
return "Hello " + name + "!";
}
}

如果需要调用,则直接执行

String s = new CommandHelloWorld("World").execute();

就可以了。

如何使用配置

作为熔断和降级的组件,Hystrix 当然必须提供一些配置,例如:在多少秒内服务异常次数超过多少次时,会触发熔断,以及熔断多少秒后,重新尝试请求服务,等等。

这些配置决定了 Hystrix 该如何工作,我们可以在 HystrixCommand 的构造过程中,对这些配置进行修改(当然,不修改的话,也是有默认配置的)。为了达成以上目的,Hystrix 需要在服务的维度上,记录时间、请求数量、是否错误等信息,从而使自己有足够的信息来判断是否应该熔断。

上面提到服务的维度,那么 Hystrix 是如何区分服务的呢?

在 Hystrix 中有两个用于对服务进行命令和区分的配置:Group key 和 Command key,分别可以理解为组关键字和命令关键字,一个组关键字中可以有多个命令关键字。

例如,可以将上面 CommandHello 中的构造函数修改为:

    public CommandHelloWorld(String name) {
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"))
.andCommandKey(HystrixCommandKey.Factory.asKey("HelloWorld")));
this.name = name;
}

其中 Setter 中就指定了当前命令的组关键字和命令关键字。

当然,上面提到的熔断等,也是可以在这个 Setter 里面进行配置的。

    public CommandHelloWorld(String name) {
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"))
.andCommandKey(HystrixCommandKey.Factory.asKey("HelloWorld"))
.andCommandPropertiesDefaults(propSetter)); // 这里配置熔断等的信息
this.name = name;
}

这里的 propSetter 是一个 HystrixCommandProperties.Setter 类的字段,其中包含了熔断等的配置,这里就不过多展开了,感兴趣的可以直接看这个类的源码。

动态配置更新的问题

什么是动态配置更新?即在应用程序运行时,对熔断等配置进行动态修改,并使得修改可以立即生效。

举个例子,对于一个服务,我本来配置的是 60s 内有 3 次请求出错就熔断,现在我想改成 20s 内有 5 次请求出错才熔断,并且需要该修改立即生效,那么 Hystrix 可以做到吗?

首先给出结论:Hystrix 可以做到。按照官方的说法,Hystrix 支持使用 Archaius 进行动态配置,详情可见官方文档 https://github.com/Netflix/Hystrix/wiki/Configuration#intro

但是,这种用法需要 Archaius 进行配合,如果在生产环境中使用,那你又要引入一个新的依赖组件 Archauis,未免有点得不偿失了。那么我们有没有办法在不引入任何新的组件前提下,从代码的角度上实现配置动态更新呢?

答案是可以的,只是需要一些骚操作。仅仅修改 HystrixCommand 构造时 Setter 里面的 CommandPropertiesDefaults 里的熔断配置,是没有用的!

那么为啥仅修改以上配置没用呢?这里涉及了 Hystrix 里两个地方,使用了缓存,导致动态修改无法生效,仍然会使用缓存的值(也就是修改之前的值)。这两个缓存分别为:

  • HystrixPropertiesFactory 里面的 commandProperties 字段,这里存储了HystrixCommand 的基本属性。
  • HystrixCircuitBreaker$Factory 里面的 circuitBreakersByCommand 字段,这里存储了 HystrixCommand 的熔断器(用于判断何时熔断以及打开/关闭熔断)。

这两个字段都是 ConcurrentHashMap 类型,其 key 为 HystrixCommand 的 commandKey。我们知道 commandKey 一般会设置为服务名称,那么也就是说:对于同一个服务,即使修改了其熔断配置,仍然会因为缓存原因,使用修改之前的配置以及熔断器,那么动态更新就无法生效了。

如何解决

找到了缓存的位置,也就找到了动态配置更新不生效的根本原因,接下来去解决就好了,解决思路很直接:当检测到配置发生改变时,主动删掉缓存 Map 中的相关项。

但是,Hystrix 似乎并没有考虑动态配置更新这一需求,以上两个缓存使用的 Map,都是静态私有字段,我们在外部理论上是不能获取并修改它们的。。

如何解决?实际也很简单,利用反射即可,我们知道利用反射可以访问到类的私有字段/方法,那么问题就可以解决了。

例如,对于 HystrixCircuitBreaker$Factory 里的 circuitBreakersByCommand ,可以使用以下方式进行缓存项清除:

try {
Field field = HystrixCircuitBreaker.Factory.class.getDeclaredField("circuitBreakersByCommand");
field.setAccessible(true);
// 由于是 static 字段,直接 get(null) 即可
ConcurrentHashMap<String, HystrixCircuitBreaker> circuitBreakersByCommand = (ConcurrentHashMap<String, HystrixCircuitBreaker>) field.get(null);
// 这里 commandKey 就是待更新的服务名
circuitBreakersByCommand.remove(commandKey);
} catch (NoSuchFieldException | IllegalAccessException e) {
log.error("Remove cache in HystrixCircuitBreaker.Factory failed, commandKey: {}", commandKey, e);
}

至于另一个缓存项,也是同样的方法,这里就不赘述了。

总之,注意以上两个地方的缓存,在需要动态配置更新时,手动将以上两个地方的缓存清除掉,就可以使得 Hystrix 轻轻松松具备动态配置更新的能力了。

Hystrix 如何在不引入 Archaius 的前提下实现动态配置更新的更多相关文章

  1. hystrix(一) 简单使用, 以及动态配置更新

    本文转载自https://my.oschina.net/u/1169457/blog/1787414 hystrix 简单使用, 以及动态配置更新 概述 只介绍同步模式下简单的使用, 有助于快速接入, ...

  2. a,b,c为3个整型变量,在不引入第四个变量的前提下写一个算法实现 a=b b=c c=a?(异或解决值互换问题)

    package com.Summer_0424.cn; /** * @author Summer * a,b,c为3个整型变量,在不引入第四个变量的前提下写一个算法实现 a=b b=c c=a? */ ...

  3. a,b为2个整型变量,在不引入第三个变量的前提下写一个算法实现 a与b的值互换

    package com.Summer_0424.cn; /** * @author Summer * a,b为2个整型变量,在不引入第三个变量的前提下写一个算法实现 a与b的值互换? */ publi ...

  4. maven在windows下的安装配置及手动引入oracle数据库jar包

    一.maven的安装配置 注意:在进行如下配置之前,有个前提是你的java的jdk安装配置正确才行 1.首先,下载maven,网址http://maven.apache.org/download.cg ...

  5. call 方法在使用一个指定的this值和若干个指定的参数值的前提下调用某个函数或方法.

    call 方法在使用一个指定的this值和若干个指定的参数值的前提下调用某个函数或方法. 注意:该函数的语法与 apply() 方法的语法几乎完全相同,唯一的区别在于,apply()方法接受的是一个参 ...

  6. 如何使用python在保留原excel格式的前提下插入/修改数据

    一.需求分析: 统计的报表中需要每日查询当天数据并追加到原有的excel后面. 因为原始excel格式已经设定好,如果使用xlwt,仅仅指定设定我们要插入的单元格的格式,原始数据的格式会被初始化. 所 ...

  7. 第一节:学会Java前提-手把手教你配置JDK环境变量

    前言 大家好,今天写一遍学会Java前提-手把手教你配置JDK环境变量的概述,希望你们喜欢 下载地址 下载jdk,和eclipse就比较简单了,提供JDK 9 地址: http://www.oracl ...

  8. 不修改模板的前提下修改VisualState中的某些值

    原文链接:不修改模板的前提下修改VisualState中的某些值 - 超威蓝火 UWP里有一件非常令人不爽的事,大部分控件只提供了Normal状态下的Background,Foreground,Bor ...

  9. 【F12】谷歌浏览器--前台效果可以在不访问服务器的前提下直接改样式看效果是否是预期值。

    F12-前台效果可以在不访问服务器的前提下直接改样式看效果是否是预期值. 1.Element---页面所有元素,通过它可以做selenium的元素定位,删除页面元素,增加页面属性(通过增加页面属性便于 ...

  10. Android DevArt4:IntentFilter学习及深入~问题描述:在不指定具体action前提下,如果有两个以上的Activity,具有完全相同的intent-filter,项目同步是否会出现异常?程序运行是否会崩溃?

    概述:GitHub IntentFilter意图过滤器,三种匹配规则:action.category.data 重点:过滤规则中必须设置 '<category android:name=&quo ...

随机推荐

  1. 采用4-20mA电流的模拟量传输

    工业上常用的总线协议RS232,RS485等,都是传输数字信号的方式.工业上普遍需要测量各类非电物理量,例如温度.压力.速度.角度等,这些都需要转换成模拟量电信号才能传输到几百米外的控制室或显示设备上 ...

  2. Docker部署Reids单机

    一.Redis镜像拉取 docker pull redis 指定版本 docker pull redis:5.0.8 二.Redis单实例安装 1.创建容器挂在目录 (-p 递归创建目录,上级目录不存 ...

  3. 基于Extjs web设计器

    通过从左边的树拖入字段到右边,编辑字段属性,在界面所见即所得 进入链接 http://www.e-ipd.com:8080/crk/public/login.aspx?ReturnUrl=%2fcrk ...

  4. Linux 里面安装多个jdk,进行切换

    alternatives --config java

  5. 【Apifox Helper】自动生成接口文档,IDEA+Apifox懒人必备

    @ 目录 前言 缘由 接口文档对接爽,整理起来真费脑 ⏲️本文阅读时长 约10分钟 前置条件 1. IDEA开发工具 2. Apifox(不必要) 主要目标 一秒生成接口文档 水图 IDEA中项目接结 ...

  6. 被冰封的 Bug:Fishhook Crash 修复纪实

    作者:郝连福,业界资深计算机技术专家,现任声网Agora 首席前端架构师.先后担任过 Principal Engineer/Engineering Director(UTStarcom).Sr. ar ...

  7. 示例:iptables限制ssh链接服务器

    linux服务器默认通过22端口用ssh协议登录,这种不安全.今天想做限制,即允许部分来源ip连接服务器. 案例目标:通过iptables规则限制对linux服务器的登录. 处理方法:编写为sh脚本, ...

  8. 基于深度学习的智能PCB板缺陷检测系统(Python+清新界面+数据集)

    摘要:智能PCB板缺陷检测系统用于智能检测工业印刷电路板(PCB)常见缺陷,自动化标注.记录和保存缺陷位置和类型,以辅助电路板的质检.本文详细介绍智能PCB板缺陷检测系统,在介绍算法原理的同时,给出P ...

  9. Moho Pro - Mac 上一款专业的二维动画制作软件,强大的功能让你尽情发挥创意

    Moho,以前被称为动画工作室专业版,是最好的质量的2D动画软件之一.这个程序是理想的专业人士寻找一个更有效的替代方法来创建动画,没有繁琐的详细逐帧处理.具有直观的界面和现成的人物和附加对象(卡通对象 ...

  10. ChatGPT3.5使用体验

    优点 1.ChatGPT 能颠覆现有的搜索引擎(百度.谷歌). 2.ChatGPT 的交互体验非常好,满足"智能助手"这种工具. 3.如何使用好ChatCPT? 回到一个经典的问题 ...