Spring Cloud学习 之 Spring Cloud Hystrix(断路器原理)
断路器定义:
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(断路器原理)的更多相关文章
- Spring Cloud 学习 之 Spring Cloud Eureka(源码分析)
Spring Cloud 学习 之 Spring Cloud Eureka(源码分析) Spring Boot版本:2.1.4.RELEASE Spring Cloud版本:Greenwich.SR1 ...
- Spring Cloud 学习 之 Spring Cloud Eureka(搭建)
Spring Boot版本:2.1.4.RELEASE Spring Cloud版本:Greenwich.SR1 文章目录 搭建服务注册中心: 注册服务提供者: 高可用注册中心: 搭建服务注册中心: ...
- Spring Cloud学习笔记--Spring Boot初次搭建
1. Spring Boot简介 初次接触Spring的时候,我感觉这是一个很难接触的框架,因为其庞杂的配置文件,我最不喜欢的就是xml文件,这种文件的可读性很不好.所以很久以来我的Spring学习都 ...
- spring cloud学习(六)Spring Cloud Config
Spring Cloud Config 参考个人项目 参考个人项目 : (希望大家能给个star~) https://github.com/FunriLy/springcloud-study/tree ...
- Spring Cloud 学习 (九) Spring Security, OAuth2
Spring Security Spring Security 是 Spring Resource 社区的一个安全组件.在安全方面,有两个主要的领域,一是"认证",即你是谁:二是& ...
- spring框架学习笔记4:SpringAOP实现原理
AOP AOP(Aspect Oriented Programming),即面向切面编程,可以说是OOP(Object Oriented Programming,面向对象编程)的补充和完善.OOP引入 ...
- Spring框架学习03——Spring Bean 的详解
1.Bean 的配置 Spring可以看做一个大型工厂,用于生产和管理Spring容器中的Bean,Spring框架支持XML和Properties两种格式的配置文件,在实际开发中常用XML格式的配置 ...
- Spring框架学习02——Spring IOC 详解
1.Spring IOC的基本概念 IOC(Inverse of Control)反转控制的概念,就是将原本在程序中手动创建对象的控制权,交由Spring框架管理.当某个Java对象(调用者)需要调用 ...
- Spring Boot学习笔记——Spring Boot与MyBatis的集成(项目示例)
1.准备数据库环境 # 创建数据库 CREATE DATABASE IF NOT EXISTS zifeiydb DEFAULT CHARSET utf8 COLLATE utf8_general_c ...
- Spring 框架学习(1)--Spring、Spring MVC扫盲
纸上得来终觉浅,绝知此事要躬行 文章大纲 什么是spring 传统Java web应用架构 更强的Java Web应用架构--MVC框架 Spring--粘合式框架 spring的内涵 spring核 ...
随机推荐
- 漏洞复现环境集锦-Vulhub
0x01 Vulhub简介 Vulhub是一个面向大众的开源漏洞靶场,无需docker知识,简单执行两条命令即可编译.运行一个完整的漏洞靶场镜像. 0x02 安装 # 安装pip curl -s ht ...
- 2019-05-25 Python之Mongodb的使用
Mongodb学习总结: one.插入数据pass two.查看数据pass three.修改数据pass four.数据排序pass five.删除数据pass 一.安装Mongodb https: ...
- GeiGebra指令
- python教程:使用 async 和 await 协程进行并发编程
python 一直在进行并发编程的优化, 比较熟知的是使用 thread 模块多线程和 multiprocessing 多进程,后来慢慢引入基于 yield 关键字的协程. 而近几个版本,python ...
- 阿里Canal框架数据库同步-实战教程
一.Canal简介: canal是阿里巴巴旗下的一款开源项目,纯Java开发.基于数据库增量日志解析,提供增量数据订阅&消费,目前主要支持了MySQL(也支持mariaDB). 二.背景介绍: ...
- L22 Data Augmentation数据增强
数据 img2083 链接:https://pan.baidu.com/s/1LIrSH51bUgS-TcgGuCcniw 提取码:m4vq 数据cifar102021 链接:https://pan. ...
- 如果这篇文章说不清epoll的本质,那就过来掐死我吧!
转载自:https://www.toutiao.com/i6683264188661367309/ 目录 一.从网卡接收数据说起 二.如何知道接收了数据? 三.进程阻塞为什么不占用cpu资源? 四.内 ...
- 转:Cookies 和 Session的区别
转自:http://blog.csdn.net/axin66ok/article/details/6175522 1.cookie 是一种发送到客户浏览器的文本串句柄,并保存在客户机硬盘上,可以用来在 ...
- MySQL笔记总结-DDL语言
DDL语言 数据类型 一.数值型 1.整型 tinyint.smallint.mediumint.int/integer.bigint 1 2 3 4 8 特点: ①都可以设置无符号和有符号,默认有符 ...
- df卡住的解决办法
在使用网络存储时,如果网络存储出问题.比如使用NFS,网络中断,df -h会卡住 情形一 ctrl+c是能取消中断的,这种情况算是比较幸运.使用mount查看有哪些挂载点,将其卸载即可. 情形二 ct ...