断路器定义:

public interface HystrixCircuitBreaker {

    // 每个Hystrix都通过它判断是否被执行
public boolean allowRequest(); // 返回当前断路器是否打开
public boolean isOpen(); // 用来闭合断路器
void markSuccess(); public static class Factory {
// 维护了一个Hystrix命令与HystrixCircuitBreaker的关系
// String类型的key通过HystrixCommandKey定义
private static ConcurrentHashMap<String, HystrixCircuitBreaker> circuitBreakersByCommand = new ConcurrentHashMap<String, HystrixCircuitBreaker>(); public static HystrixCircuitBreaker getInstance(HystrixCommandKey key, HystrixCommandGroupKey group, HystrixCommandProperties properties, HystrixCommandMetrics metrics) {
HystrixCircuitBreaker previouslyCached = circuitBreakersByCommand.get(key.name());
if (previouslyCached != null) {
return previouslyCached;
} HystrixCircuitBreaker cbForCommand = circuitBreakersByCommand.putIfAbsent(key.name(), new HystrixCircuitBreakerImpl(key, group, properties, metrics));
if (cbForCommand == null) { return circuitBreakersByCommand.get(key.name());
} else { return cbForCommand;
}
} public static HystrixCircuitBreaker getInstance(HystrixCommandKey key) {
return circuitBreakersByCommand.get(key.name());
} static void reset() {
circuitBreakersByCommand.clear();
}
} static class HystrixCircuitBreakerImpl implements HystrixCircuitBreaker {
// 断路器对应的HystrixCommand实例的属性对象
private final HystrixCommandProperties properties;
// 用来让HystrixCommand记录各类度量指标的对象
private final HystrixCommand记录各类度量指标的对象Metrics metrics;
// 断路器是否打开的标志,默认未false
private AtomicBoolean circuitOpen = new AtomicBoolean(false);
// 断路器上次打开的时间戳
private AtomicLong circuitOpenedOrLastTestedTime = new AtomicLong();
protected HystrixCircuitBreakerImpl(HystrixCommandKey key, HystrixCommandGroupKey commandGroup, HystrixCommandProperties properties, HystrixCommandMetrics metrics) {
this.properties = properties;
this.metrics = metrics;
}
// 在半开路的情况下使用,若Hystrix命令调用成功,通过调用它将打开的断路器关闭
// 并重置度量指标
public void markSuccess() {
if (circuitOpen.get()) {
if (circuitOpen.compareAndSet(true, false)) { metrics.resetStream();
}
}
}
// 判断请求是否被允许,先根据配置对象中断路器
@Override
public boolean allowRequest() {
if (properties.circuitBreakerForceOpen().get()) {
// 配置了强制打开,直接返回false
return false;
}
if (properties.circuitBreakerForceClosed().get()) {
// 配置了强制关闭,会允许所有请求,但同时也会调用isOpen()来执行断路器的计算逻辑
isOpen(); return true;
}
// 默认情况下,会用过!isOpen() || allowSingleTest(),来判断请求是否被允许
// 也就是说,断路器闭合,或者断路器关闭,但是allowSingleTest()为true
return !isOpen() || allowSingleTest(),;
} public boolean allowSingleTest() {
long timeCircuitOpenedOrWasLastTested = circuitOpenedOrLastTestedTime.get();
// 断路器打开的情况下,每隔一段事件允许请求一次,默认为5s
// 此时断路器处于一个半开路的状态下
if (circuitOpen.get() && System.currentTimeMillis() > timeCircuitOpenedOrWasLastTested + properties.circuitBreakerSleepWindowInMilliseconds().get()) { if (circuitOpenedOrLastTestedTime.compareAndSet(timeCircuitOpenedOrWasLastTested, System.currentTimeMillis())) { return true;
}
}
return false;
}
// 判断当前断路器是否打开
@Override
public boolean isOpen() {
if (circuitOpen.get()) {
// 如果断路器打开的标志为true就直接返回true,,表示断路器在打开状态
return true;
}
// 否则从度量指标对象中获取HealthCounts统计对象做进一步判断(该对象记录了一个滚动事件窗内 的请求信息快照,默认时间窗为10秒)
HealthCounts health = metrics.getHealthCounts(); if (health.getTotalRequests() <
//如果他的QPS在预设的阈值范围内就返回false,表示断路器处于闭合状态。
//该值的默认值为20
properties.circuitBreakerRequestVolumeThreshold().get()) { return false;
} if (health.getErrorPercentage() <
// 错误百分比在阈值内就返回false,该阈值默认为50%
properties.circuitBreakerErrorThresholdPercentage().get()) {
return false;
} else {
// 如果上面两个参数都不满足,就打开断路器
if (circuitOpen.compareAndSet(false, true)) {
circuitOpenedOrLastTestedTime.set(System.currentTimeMillis());
return true;
} else { return true;
}
}
} }
// 定义了一个什么都不做的断路器
static class NoOpCircuitBreaker implements HystrixCircuitBreaker { @Override
public boolean allowRequest() {
return true;
} @Override
public boolean isOpen() {
return false;
} @Override
public void markSuccess() { } } }

Spring Cloud学习 之 Spring Cloud Hystrix(断路器原理)的更多相关文章

  1. Spring Cloud 学习 之 Spring Cloud Eureka(源码分析)

    Spring Cloud 学习 之 Spring Cloud Eureka(源码分析) Spring Boot版本:2.1.4.RELEASE Spring Cloud版本:Greenwich.SR1 ...

  2. Spring Cloud 学习 之 Spring Cloud Eureka(搭建)

    Spring Boot版本:2.1.4.RELEASE Spring Cloud版本:Greenwich.SR1 文章目录 搭建服务注册中心: 注册服务提供者: 高可用注册中心: 搭建服务注册中心: ...

  3. Spring Cloud学习笔记--Spring Boot初次搭建

    1. Spring Boot简介 初次接触Spring的时候,我感觉这是一个很难接触的框架,因为其庞杂的配置文件,我最不喜欢的就是xml文件,这种文件的可读性很不好.所以很久以来我的Spring学习都 ...

  4. spring cloud学习(六)Spring Cloud Config

    Spring Cloud Config 参考个人项目 参考个人项目 : (希望大家能给个star~) https://github.com/FunriLy/springcloud-study/tree ...

  5. Spring Cloud 学习 (九) Spring Security, OAuth2

    Spring Security Spring Security 是 Spring Resource 社区的一个安全组件.在安全方面,有两个主要的领域,一是"认证",即你是谁:二是& ...

  6. spring框架学习笔记4:SpringAOP实现原理

    AOP AOP(Aspect Oriented Programming),即面向切面编程,可以说是OOP(Object Oriented Programming,面向对象编程)的补充和完善.OOP引入 ...

  7. Spring框架学习03——Spring Bean 的详解

    1.Bean 的配置 Spring可以看做一个大型工厂,用于生产和管理Spring容器中的Bean,Spring框架支持XML和Properties两种格式的配置文件,在实际开发中常用XML格式的配置 ...

  8. Spring框架学习02——Spring IOC 详解

    1.Spring IOC的基本概念 IOC(Inverse of Control)反转控制的概念,就是将原本在程序中手动创建对象的控制权,交由Spring框架管理.当某个Java对象(调用者)需要调用 ...

  9. Spring Boot学习笔记——Spring Boot与MyBatis的集成(项目示例)

    1.准备数据库环境 # 创建数据库 CREATE DATABASE IF NOT EXISTS zifeiydb DEFAULT CHARSET utf8 COLLATE utf8_general_c ...

  10. Spring 框架学习(1)--Spring、Spring MVC扫盲

    纸上得来终觉浅,绝知此事要躬行 文章大纲 什么是spring 传统Java web应用架构 更强的Java Web应用架构--MVC框架 Spring--粘合式框架 spring的内涵 spring核 ...

随机推荐

  1. 在IDEA中搭建Java源码学习环境并上传到GitHub上

    打开IDEA新建一个项目 创建一个最简单的Java项目即可 在项目命名填写该项目的名称,我这里写的项目名为Java_Source_Study 点击Finished,然后在项目的src目录下新建源码文件 ...

  2. AJ学IOS 之小知识iOS启动动画_Launch Screen的运用

    AJ 分享,必须精品 看下效果吧 例如新浪微博的软件开启时候 就是这个 用Launch image实现 这个不难,就是在Images.xcassets 增加一个LaunchImage文件(右键 new ...

  3. AJ学IOS(36)UI之手势事件旋转_缩放_拖拽

    AJ分享,必须精品 效果 完成一个图片的捏合缩放,拖拽,旋转动作. 设计思路 拖拽: 首先是最简单的拖拽 //拖拽 -(void)panTest { UIPanGestureRecognizer *p ...

  4. AJ整理问题之:内存堆栈

    内存 数据在内存中的存放 在计算机中,运行的应用程序的数据都是保存在内存中的. 不同类型的数据,保存的内存区域不同,其中包括: 1:栈区(stack)由编译器自动分配并释放,一半存放函数的参数值,局部 ...

  5. C#多线程(6):线程通知

    目录 AutoRestEvent 类 常用方法 一个简单的示例 解释一下 复杂一点的示例 解释 回顾一下,前面 lock.Monitor 部分我们学习了线程锁,Mutex 部分学习了进程同步,Sema ...

  6. google protobuf c++ 反射

    const Descriptor *desc = DescriptorPool::generated_pool()->FindMessageTypeByName(msg_name); asser ...

  7. mac上安装htop

    对于经常在mac上使用top命令的童鞋来说,htop会是一个更加好看和更加好用的命令,下面就是在mac上安装htop的步骤 1.首先去htop官网去下载,我下的是最新的2.2.0版本,网址是https ...

  8. api_DZFPKJ & api_DZFPCX

    AES加密算法的网站:http://www.ssleye.com/aes_cipher.html """ AES加密(加解密算法/工作模式/填充方式:AES/ECB/PK ...

  9. 基于netty实现rpc框架-spring boot服务端

    demo地址 https://gitee.com/syher/grave-netty RPC介绍 首先了解一下RPC:远程过程调用.简单点说就是本地应用可以调用远程服务器的接口.那么通过什么方式调用远 ...

  10. (一)C# Windows Mobile 半透明窗体

    Windows Mobile,个人心中臻至完美的系统. 不忍自己对WM的钻研成果消逝,故留作纪念. 系列开篇,便是一个曾令自己困扰很久的问题:如何实现半透明窗体. 如果了解Win32编程,其实很简单. ...