断路器定义:

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. 如何实现Jenkins 编译结果通知到QQ好友及QQ群组<很遗憾 2019年1月1日腾讯停止了webqq机器人的服务支持>

    Jenkins-NotifyQQ NotifyQQ 运行于Docker 本文介绍mac 环境下实现Jenkins编译结果QQ即时通知 Jenkins 安装使用及iOS自动化打包,邮件通知请参考本人博客 ...

  2. 007-函数-C语言笔记

    007-函数-C语言笔记 学习目标 1.[了解]函数的分类 2.[掌握]函数的声明定义和调用 3.[掌握]函数的形参和实参 4.[掌握]带返回值的函数 5.[掌握]全局变量和局部变量 6.[了解]注释 ...

  3. AJ学IOS(41)UI之核心动画 两行代码搞定3D转场

    AJ分享,必须精品 效果: 代码: 其实代码很少,苹果都给封装好了 // 1.创建核心动画 CATransition *ca = [CATransition animation]; // 1.1动画过 ...

  4. Nginx+uWSGI+Python+Django构建必应高清壁纸站

    写在前面 做这个网站的初衷是因为,每次打开必应搜索搜东西的时候都会被上面的背景图片吸引,我想必应的壁纸应该是经过专业人员精选出来的,我甚至会翻看以前的历史图片,唯一美中不足的是必应的首页只能查看最多7 ...

  5. 图2-4TCP状态转换图

    这张图中描述了TCP中11个状态的转换. 光看这个图我一开始是蒙蔽的,也没有写服务器和客户端的操作流程.不过回头一想,是状态转换,也就是从一个状态到另外一个状态发生了什么,什么条件触发的.这样是不是好 ...

  6. JavaScript_Array

    Array 概念特点 值的有序集合: 每一个值叫一个元素: 每个元素在数组中有一个位置,以数字表示,称为索引(下标): 元素可以是任何类型 索引从0开始,最大为2的32次方 数组的创建 数组直接量 v ...

  7. 2. Git-命令行-删除本地和远程分支

    命令行方式 Git Bash: 切换到要操作的项目文件夹 命令行 : $ cd <ProjectPath> 查看项目的分支们(包括本地和远程) 命令行 : $ git branch -a ...

  8. Stream—一个早产的婴儿

    当你会关注这篇文章时,那么意味着你对Stream或多或少有些了解,甚至你在许多业务中有所应用.正如你所知,业界对Stream.lambda褒贬不一,有人认为它是银弹,也有人认为其降低了代码的可读性.事 ...

  9. Java中的字符串操作(比较String,StringBuiler和StringBuffer)

    一.前言 刚开始学习Java时,作为只会C语言的小白,就为其中的字符串操作而感到震撼.相比之下,C语言在字节数组中保存一个结尾的\0去表示字符串,想实现字符串拼接,还需要调用strcpy库函数或者自己 ...

  10. 用Python的Plotly画出炫酷的数据可视化(含各类图介绍,附代码)

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 我被狗咬了 在谈及数据可视化的时候,我们通常都会使用到matplo ...