Spring中使用Hystrix实现熔断详解

 更新时间:2023年12月14日 08:32:18   作者:Terisadeng  
这篇文章主要介绍了Java中使用Hystrix实现熔断详解,对于第一个问题,查看hystrix源码可以看到,如果有缓存配置是优先使用的缓存的,因此如果配置更新,必须要更新缓存,不能使用Hystrix.reset()方法来更新缓存,需要的朋友可以参考下

Hystrix实现熔断

在使用Hystrix实现熔断的过程中遇到了两个问题

1、在修改了熔断配置之后不生效的问题

2、熔断后不恢复的问题

对于第一个问题,查看hystrix源码可以看到,如果有缓存配置是优先使用的缓存的,因此如果配置更新,必须要更新缓存,不能使用Hystrix.reset()方法来更新缓存,这个方法清理全局缓存,会影响其他commandkey的熔断状态。

public static HystrixCircuitBreaker getInstance(HystrixCommandKey key, HystrixCommandGroupKey group, HystrixCommandProperties properties, HystrixCommandMetrics metrics) {
            // this should find it for all but the first time
            HystrixCircuitBreaker previouslyCached = circuitBreakersByCommand.get(key.name());
            if (previouslyCached != null) {
                return previouslyCached;
            }

官方提供的方法是通过archaius动态更新

Hystrix uses Archaius for the default implementation of properties for configuration.

实现接口com.netflix.config.PolledConfigurationSource,将对应的commandkey通过形如下面的key来放入poll方法响应的map中,hystrix会根据这个key自动更新缓存

hystrix.command.HystrixCommandKey.execution.isolation.thread.timeoutInMilliseconds

第二个问题经过debughystrix源码发现是由于,使用了响应式的调用,hystrix使用的是V1版本的rxjava,而项目使用的是V3版本的rxjava,在V3转V1后响应给hystrixcircuitbreaker时,hystrix没有收到oncomplete事件,导致没有在断路器半开状态时调用成功关闭断路器。

在com.netflix.hystrix.AbstractCommand类中实现了断路器的控制逻辑:

可以看到在onCompleted的观察者逻辑中会将断路器markSuccess

private Observable<R> executeCommandAndObserve(final AbstractCommand<R> _cmd) {
        final HystrixRequestContext currentRequestContext = HystrixRequestContext.getContextForCurrentThread();
 
        final Action1<R> markEmits = new Action1<R>() {
            @Override
            public void call(R r) {
                if (shouldOutputOnNextEvents()) {
                    executionResult = executionResult.addEvent(HystrixEventType.EMIT);
                    eventNotifier.markEvent(HystrixEventType.EMIT, commandKey);
                }
                if (commandIsScalar()) {
                    long latency = System.currentTimeMillis() - executionResult.getStartTimestamp();
                    eventNotifier.markCommandExecution(getCommandKey(), properties.executionIsolationStrategy().get(), (int) latency, executionResult.getOrderedList());
                    eventNotifier.markEvent(HystrixEventType.SUCCESS, commandKey);
                    executionResult = executionResult.addEvent((int) latency, HystrixEventType.SUCCESS);
                    circuitBreaker.markSuccess();
                }
            }
        };
 
        final Action0 markOnCompleted = new Action0() {
            @Override
            public void call() {
                if (!commandIsScalar()) {
                    long latency = System.currentTimeMillis() - executionResult.getStartTimestamp();
                    eventNotifier.markCommandExecution(getCommandKey(), properties.executionIsolationStrategy().get(), (int) latency, executionResult.getOrderedList());
                    eventNotifier.markEvent(HystrixEventType.SUCCESS, commandKey);
                    executionResult = executionResult.addEvent((int) latency, HystrixEventType.SUCCESS);
                    circuitBreaker.markSuccess();
                }
            }
        };

目前想到的解决办法是一种是在接收调用服务响应时blockingfirst(),但是这样会导致异步调用变成同步,还有一种是在调用服务的Observable的onnext方法中添加onCompleted事件,来通知hystrix调用服务接收到了complete事件,但是这样就只能接收到单个onNext事件,两种都有缺点,还有想到更好的解决办法。

到此这篇关于Spring中使用Hystrix实现熔断详解的文章就介绍到这了,更多相关Hystrix实现熔断内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • spring-Kafka中的@KafkaListener深入源码解读

    spring-Kafka中的@KafkaListener深入源码解读

    本文主要通过深入了解源码,梳理从spring启动到真正监听kafka消息的这套流程,从spring启动开始处理@KafkaListener,本文结合实例流程图给大家讲解的非常详细,需要的朋友参考下
    2023-02-02
  • Mybatis-plus批量去重插入ON DUPLICATE key update使用方式

    Mybatis-plus批量去重插入ON DUPLICATE key update使用方式

    这篇文章主要介绍了Mybatis-plus批量去重插入ON DUPLICATE key update使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • JAVA判断空值方法原理解析

    JAVA判断空值方法原理解析

    这篇文章主要介绍了JAVA判断空值方法原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-05-05
  • Log4j_配置方法(全面讲解)

    Log4j_配置方法(全面讲解)

    下面小编就为大家带来一篇Log4j_配置方法(全面讲解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • springboot项目中PropertySource如何读取yaml配置文件

    springboot项目中PropertySource如何读取yaml配置文件

    这篇文章主要介绍了springboot项目中PropertySource如何读取yaml配置文件问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • Java中关于MouseWheelListener的鼠标滚轮事件详解

    Java中关于MouseWheelListener的鼠标滚轮事件详解

    这篇文章主要介绍了Java中关于MouseWheelListener的鼠标滚轮事件详解,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • Java经典用法总结(二)

    Java经典用法总结(二)

    这篇文章主要介绍了Java经典用法总结,在本文中,尽量收集一些java最常用的习惯用法,特别是很难猜到的用法,本文重点讲解了java应用和输入输出常用方法,感兴趣的小伙伴们可以参考一下
    2016-02-02
  • 如何解决Gradle、Maven项目build后没有mybatis的mapper.xml文件的问题

    如何解决Gradle、Maven项目build后没有mybatis的mapper.xml文件的问题

    这篇文章主要介绍了如何解决Gradle、Maven项目build后没有mybatis的mapper.xml文件的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • spring boot集成pagehelper(两种方式)

    spring boot集成pagehelper(两种方式)

    这篇文章主要介绍了spring boot集成pagehelper(两种方式),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-01-01
  • 详解Java中Thread 和Runnable区别

    详解Java中Thread 和Runnable区别

    这篇文章主要介绍了Java中Thread 和Runnable的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03

最新评论