断路器定义:

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. SpringBoot系列(六)集成thymeleaf详解版

    SpringBoot系列(六)集成thymeleaf详解版 1. thymeleaf简介  1. Thymeleaf是适用于Web和独立环境的现代服务器端Java模板引擎.  2. Thymeleaf ...

  2. FreeRTOS操作系统工程建立和操作系统的概念

    一.建立工程步骤如下: 二.详细步骤流程如下: 1.新建工程文件夹,然后在里面建立如下几个文件: 2.使用keil5建立工程: a.建立工程: b.添加内核文件: 3.建立文件分组: 4.创建main ...

  3. 记一次错误 POST http://127.0.0.1:8000/auth/signup/ 500 (Internal Server Error)

    错误环境: 1,ajax 发送 post 请求调用 views 的视图 xfzajax.post({ 'url': '/xfzauth/signup/', 'data': { 'telephone': ...

  4. ASE project demo:pdf

    欢迎使用 pdf ~ 主页面如下,整个app风格一致,保持简约舒适的视觉体验~ 侧边栏打开,可选择打开新的pdf文件,返回主页面,打开本地生词本,登录等操作~ 可以点击侧边栏OpenFile打开新的p ...

  5. Django系列操作

    每次用到都去百度找....找的还不行~~得自己改~~耗时耗力虽然不难~~~直接贴代码记录下方便自己用~~~~ Django之分页 定义成一个块,直接引用到对应的位置即可... <div clas ...

  6. 使用GML的八方向自动寻路

    使用GML的八方向自动寻路 本教程适合无基础人员使用. 提示 本教程中仅使用了最简单的方法,并且有一些错误和不规范之处.请谅解一下,在评论区提出,我会修改.古人曰"教学相长",希望 ...

  7. 泛微ecology OA系统在数据库配置信息泄露

    漏洞描述 攻击者可通过该漏洞页面直接获取到数据库配置信息,攻击者可通过访问存在漏洞的页面并解密从而获取数据库配置信息,如攻击者可直接访问数据库,则可直接获取用户数据,由于泛微e-cology默认数据库 ...

  8. 干货福利:如何使用Python中Django模板?

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 穆胜亮 篇文章将学习如何使用Django模板.模板是在Django ...

  9. token认证和理解

    认知篇:https://blog.csdn.net/FYGu18/article/details/89345490 token失效篇认知:https://segmentfault.com/q/1010 ...

  10. 编译原理-第四章 语法分析-4.6 简单LR技术

    简单LR分析方法 一.LR语言分析器模型与算法 1.输入.输出.栈和方法 2.LR语法分析表 3.LR分析程序 4.例 例1: 例2: 二.LR语法分析算法 1.LR语法分析算法的定义和概念 定义: ...