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核 ...
随机推荐
- 发布公开的pod
发布公开的pod 方便项目 通过cocoapods 使用,便于版本版本管理,下面是简单步奏: 0.首次操作先要注册Trunk: pod trunk register zhujin001xb@163.c ...
- substr和substring之间的区别
substr 和 substring都是JS 截取字符串函数,两者用法很相近,下面是两者的语法很示例: substr 方法 返回一个从指定位置开始的指定长度的子字符串.stringvar.substr ...
- work of 1/4/2016
part 组员 今日工作 工作耗时/h 明日计划 工作耗时/h UI 冯晓云 修改UI增强显示鲁棒 6 完成UI页面切换部分 ...
- Gradle系列之Groovy基础篇
原文发于微信公众号 jzman-blog,欢迎关注交流. 上一篇学习了 Gradle 的入门知识,Gradle 基于 Groovy,今天学习一下 Groovy 的基础知识,Groovy 是基于 JVM ...
- js的中文英文排序
本例主要实现 中文汉字按拼音排序的方法和英文按照首字母排序的方法. //要排序的数据 let data = [ {chinese: '蔡司', english: 'Chase'}, {chinese: ...
- [php代码审计]bluecms v1.6 sp1
一.环境搭建 bluecms v1.6 sp1源码 windows 7 phpstudy2016(php 5.4.45) seay源代码审计系统 源码在网上很容易下载,很多教程说访问地址 http:/ ...
- bypass安全狗测试学习
搭建简单的sql注入环境 在test数据库中创建sqltest表,插入字段数据 编写存在注入的php文件 <?php $id = $_REQUEST['uid']; echo "您当前 ...
- MySql的数据库方言问题
在使用hibernate将po(一般对象类)转化为数据库表时,如果mysql的版本为5.0之前的,则方言写为:<property name="dialect">org. ...
- Asp.Net Core 3.1 的启动过程5
前言 本文主要讲的是Asp.Net Core的启动过程,帮助大家掌握应用程序的关键配置点. 1.创建项目 1.1.用Visual Studio 2019 创建WebApi项目. 这里面可以看到有两个关 ...
- (第五篇)Linux操作系统基本结构介绍
Linux操作系统基本结构介绍 Linux系统一般有4个主要部分:内核.shell.文件系统和应用程序.内核.shell和文件系统一起形成了基本的操作系统结构,它们使得用户可以运行程序.管理文件并使用 ...