Spring Cloud学习 之 Spring Cloud Hystrix(断路器原理)

简介: 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() {
        }
    }
}
相关文章
|
5天前
|
XML Java 开发者
Spring Boot开箱即用可插拔实现过程演练与原理剖析
【11月更文挑战第20天】Spring Boot是一个基于Spring框架的项目,其设计目的是简化Spring应用的初始搭建以及开发过程。Spring Boot通过提供约定优于配置的理念,减少了大量的XML配置和手动设置,使得开发者能够更专注于业务逻辑的实现。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,为开发者提供一个全面的理解。
16 0
|
1月前
|
Java Spring 容器
Spring底层原理大致脉络
Spring底层原理大致脉络
|
1月前
|
XML 前端开发 Java
拼多多1面:聊聊Spring MVC的工作原理!
本文详细剖析了Spring MVC的工作原理,涵盖其架构、工作流程及核心组件。Spring MVC采用MVC设计模式,通过DispatcherServlet、HandlerMapping、Controller和ViewResolver等组件高效处理Web请求。文章还探讨了DispatcherServlet的初始化和请求处理流程,以及HandlerMapping和Controller的角色。通过理解这些核心概念,开发者能更好地构建可维护、可扩展的Web应用。适合面试准备和技术深挖
42 0
|
1月前
|
负载均衡 Java API
Spring Cloud原理详解
Spring Cloud原理详解
68 0
|
API
springcloud之hystrix熔断器-Finchley.SR2版
本篇和大家分享的是springcloud-hystrix熔断器,其主要功能是对某模块调用失败做断路和降级,简单点就当某个模块程序出问题了并达到某阈值就限制后面请求,并降级的方式提供一个默认返回数据。最近在琢磨hystrix源码,琢磨思路写一个自己的简易熔断器,希望大家后期关注。
2851 0
|
2月前
|
SQL 监控 druid
springboot-druid数据源的配置方式及配置后台监控-自定义和导入stater(推荐-简单方便使用)两种方式配置druid数据源
这篇文章介绍了如何在Spring Boot项目中配置和监控Druid数据源,包括自定义配置和使用Spring Boot Starter两种方法。
|
1月前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
163 2
|
3月前
|
缓存 Java Maven
Java本地高性能缓存实践问题之SpringBoot中引入Caffeine作为缓存库的问题如何解决
Java本地高性能缓存实践问题之SpringBoot中引入Caffeine作为缓存库的问题如何解决
|
10天前
|
缓存 IDE Java
SpringBoot入门(7)- 配置热部署devtools工具
SpringBoot入门(7)- 配置热部署devtools工具
22 2
 SpringBoot入门(7)- 配置热部署devtools工具
|
6天前
|
存储 运维 安全
Spring运维之boot项目多环境(yaml 多文件 proerties)及分组管理与开发控制
通过以上措施,可以保证Spring Boot项目的配置管理在专业水准上,并且易于维护和管理,符合搜索引擎收录标准。
18 2