本文主要研究一下resilience4j的CircuitBreakerStateMachine

CircuitBreakerStateMachine

resilience4j-circuitbreaker-0.13.0-sources.jar!/io/github/resilience4j/circuitbreaker/internal/CircuitBreakerStateMachine.java

/*** A CircuitBreaker finite state machine.*/
public final class CircuitBreakerStateMachine implements CircuitBreaker {private static final Logger LOG = LoggerFactory.getLogger(CircuitBreakerStateMachine.class);private final String name;private final AtomicReference<CircuitBreakerState> stateReference;private final CircuitBreakerConfig circuitBreakerConfig;private final CircuitBreakerEventProcessor eventProcessor;/*** Creates a circuitBreaker.** @param name                 the name of the CircuitBreaker* @param circuitBreakerConfig The CircuitBreaker configuration.*/public CircuitBreakerStateMachine(String name, CircuitBreakerConfig circuitBreakerConfig) {this.name = name;this.circuitBreakerConfig = circuitBreakerConfig;this.stateReference = new AtomicReference<>(new ClosedState(this));this.eventProcessor = new CircuitBreakerEventProcessor();}/*** Creates a circuitBreaker with default config.** @param name the name of the CircuitBreaker*/public CircuitBreakerStateMachine(String name) {this(name, CircuitBreakerConfig.ofDefaults());}/*** Creates a circuitBreaker.** @param name                 the name of the CircuitBreaker* @param circuitBreakerConfig The CircuitBreaker configuration supplier.*/public CircuitBreakerStateMachine(String name, Supplier<CircuitBreakerConfig> circuitBreakerConfig) {this(name, circuitBreakerConfig.get());}/*** Requests permission to call this backend.** @return true, if the call is allowed.*/@Overridepublic boolean isCallPermitted() {boolean callPermitted = stateReference.get().isCallPermitted();if (!callPermitted) {publishCallNotPermittedEvent();}return callPermitted;}@Overridepublic void onError(long durationInNanos, Throwable throwable) {if (circuitBreakerConfig.getRecordFailurePredicate().test(throwable)) {if (LOG.isDebugEnabled()) {LOG.debug(String.format("CircuitBreaker '%s' recorded a failure:", name), throwable);}publishCircuitErrorEvent(name, durationInNanos, throwable);stateReference.get().onError(throwable);} else {publishCircuitIgnoredErrorEvent(name, durationInNanos, throwable);}}@Overridepublic void onSuccess(long durationInNanos) {publishSuccessEvent(durationInNanos);stateReference.get().onSuccess();}/*** Get the state of this CircuitBreaker.** @return the the state of this CircuitBreaker*/@Overridepublic State getState() {return this.stateReference.get().getState();}/*** Get the name of this CircuitBreaker.** @return the the name of this CircuitBreaker*/@Overridepublic String getName() {return this.name;}/*** Get the config of this CircuitBreaker.** @return the config of this CircuitBreaker*/@Overridepublic CircuitBreakerConfig getCircuitBreakerConfig() {return circuitBreakerConfig;}@Overridepublic Metrics getMetrics() {return this.stateReference.get().getMetrics();}/*** {@inheritDoc}*/@Overridepublic String toString() {return String.format("CircuitBreaker '%s'", this.name);}@Overridepublic void reset() {CircuitBreakerState previousState = stateReference.getAndUpdate(currentState -> new ClosedState(this));if (previousState.getState() != CLOSED) {publishStateTransitionEvent(StateTransition.transitionBetween(previousState.getState(), CLOSED));}publishResetEvent();}private void stateTransition(State newState, Function<CircuitBreakerState, CircuitBreakerState> newStateGenerator) {CircuitBreakerState previousState = stateReference.getAndUpdate(currentState -> {if (currentState.getState() == newState) {return currentState;}return newStateGenerator.apply(currentState);});if (previousState.getState() != newState) {publishStateTransitionEvent(StateTransition.transitionBetween(previousState.getState(), newState));}}@Overridepublic void transitionToDisabledState() {stateTransition(DISABLED, currentState -> new DisabledState(this));}@Overridepublic void transitionToForcedOpenState() {stateTransition(FORCED_OPEN, currentState -> new ForcedOpenState(this));}@Overridepublic void transitionToClosedState() {stateTransition(CLOSED, currentState -> new ClosedState(this, currentState.getMetrics()));}@Overridepublic void transitionToOpenState() {stateTransition(OPEN, currentState -> new OpenState(this, currentState.getMetrics()));}@Overridepublic void transitionToHalfOpenState() {stateTransition(HALF_OPEN, currentState -> new HalfOpenState(this));}//......
}
复制代码
  • CircuitBreakerStateMachine实现了CircuitBreakerStateMachine接口
  • AtomicReference用来记录当前断路器的状态
  • 状态转换接口内部都调用了stateTransition方法,里头主要是更新AtomicReference以及发布事件
  • stateTransition以及reset方法里头都调用了StateTransition.transitionBetween来发布事件
  • CircuitBreakerEventProcessor用来处理事件

CircuitBreakerState

resilience4j-circuitbreaker-0.13.0-sources.jar!/io/github/resilience4j/circuitbreaker/internal/CircuitBreakerState.java

/*** Abstract state of the CircuitBreaker state machine.*/
abstract class CircuitBreakerState{CircuitBreakerStateMachine stateMachine;CircuitBreakerState(CircuitBreakerStateMachine stateMachine) {this.stateMachine = stateMachine;}abstract boolean isCallPermitted();abstract void onError(Throwable throwable);abstract void onSuccess();abstract CircuitBreaker.State getState();abstract CircuitBreakerMetrics getMetrics();/*** Should the CircuitBreaker in this state publish events* @return a boolean signaling if the events should be published*/boolean shouldPublishEvents(CircuitBreakerEvent event){return event.getEventType().forcePublish || getState().allowPublish;}
}
复制代码
  • CircuitBreakerState与CircuitBreakerStateMachine二者相互保存各自的引用
  • CircuitBreakerState的子类有OpenState、HalfOpenState、ForcedOpenState、ClosedState、DisabledState
  • 每个子类的onError、onSuccess方法自己判断是否进行状态转移,如果要转移会调用CircuitBreakerStateMachine的transitionTo开头的方法

StateTransition.transitionBetween

resilience4j-circuitbreaker-0.13.0-sources.jar!/io/github/resilience4j/circuitbreaker/CircuitBreaker.java

    /*** State transitions of the CircuitBreaker state machine.*/enum StateTransition {CLOSED_TO_OPEN(State.CLOSED, State.OPEN),CLOSED_TO_DISABLED(State.CLOSED, State.DISABLED),CLOSED_TO_FORCED_OPEN(State.CLOSED, State.FORCED_OPEN),HALF_OPEN_TO_CLOSED(State.HALF_OPEN, State.CLOSED),HALF_OPEN_TO_OPEN(State.HALF_OPEN, State.OPEN),HALF_OPEN_TO_DISABLED(State.HALF_OPEN, State.DISABLED),HALF_OPEN_TO_FORCED_OPEN(State.HALF_OPEN, State.FORCED_OPEN),OPEN_TO_CLOSED(State.OPEN, State.CLOSED),OPEN_TO_HALF_OPEN(State.OPEN, State.HALF_OPEN),OPEN_TO_DISABLED(State.OPEN, State.DISABLED),OPEN_TO_FORCED_OPEN(State.OPEN, State.FORCED_OPEN),FORCED_OPEN_TO_CLOSED(State.FORCED_OPEN, State.CLOSED),FORCED_OPEN_TO_OPEN(State.FORCED_OPEN, State.OPEN),FORCED_OPEN_TO_DISABLED(State.FORCED_OPEN, State.DISABLED),FORCED_OPEN_TO_HALF_OPEN(State.FORCED_OPEN, State.HALF_OPEN),DISABLED_TO_CLOSED(State.DISABLED, State.CLOSED),DISABLED_TO_OPEN(State.DISABLED, State.OPEN),DISABLED_TO_FORCED_OPEN(State.DISABLED, State.FORCED_OPEN),DISABLED_TO_HALF_OPEN(State.DISABLED, State.HALF_OPEN);private final State fromState;private final State toState;private static final Map<Tuple2<State, State>, StateTransition> STATE_TRANSITION_MAP =Arrays.stream(StateTransition.values()).collect(Collectors.toMap(v -> Tuple.of(v.fromState, v.toState), Function.identity()));private boolean matches(State fromState, State toState) {return this.fromState == fromState && this.toState == toState;}public static StateTransition transitionBetween(State fromState, State toState){final StateTransition stateTransition = STATE_TRANSITION_MAP.get(Tuple.of(fromState, toState));if(stateTransition == null) {throw new IllegalStateException(String.format("Illegal state transition from %s to %s", fromState.toString(), toState.toString()));}return stateTransition;}StateTransition(State fromState, State toState) {this.fromState = fromState;this.toState = toState;}public State getFromState() {return fromState;}public State getToState() {return toState;}@Overridepublic String toString(){return String.format("State transition from %s to %s", fromState, toState);}}
复制代码
  • StateTransition定义了一系列状态转换的路径
  • StateTransition.transitionBetween方法会对这些状态转换进行校验,不合法的抛出IllegalStateException

CircuitBreakerEventProcessor

resilience4j-circuitbreaker-0.13.0-sources.jar!/io/github/resilience4j/circuitbreaker/internal/CircuitBreakerStateMachine.java

    private class CircuitBreakerEventProcessor extends EventProcessor<CircuitBreakerEvent> implements EventConsumer<CircuitBreakerEvent>, EventPublisher {@Overridepublic EventPublisher onSuccess(EventConsumer<CircuitBreakerOnSuccessEvent> onSuccessEventConsumer) {registerConsumer(CircuitBreakerOnSuccessEvent.class, onSuccessEventConsumer);return this;}@Overridepublic EventPublisher onError(EventConsumer<CircuitBreakerOnErrorEvent> onErrorEventConsumer) {registerConsumer(CircuitBreakerOnErrorEvent.class, onErrorEventConsumer);return this;}@Overridepublic EventPublisher onStateTransition(EventConsumer<CircuitBreakerOnStateTransitionEvent> onStateTransitionEventConsumer) {registerConsumer(CircuitBreakerOnStateTransitionEvent.class, onStateTransitionEventConsumer);return this;}@Overridepublic EventPublisher onReset(EventConsumer<CircuitBreakerOnResetEvent> onResetEventConsumer) {registerConsumer(CircuitBreakerOnResetEvent.class, onResetEventConsumer);return this;}@Overridepublic EventPublisher onIgnoredError(EventConsumer<CircuitBreakerOnIgnoredErrorEvent> onIgnoredErrorEventConsumer) {registerConsumer(CircuitBreakerOnIgnoredErrorEvent.class, onIgnoredErrorEventConsumer);return this;}@Overridepublic EventPublisher onCallNotPermitted(EventConsumer<CircuitBreakerOnCallNotPermittedEvent> onCallNotPermittedEventConsumer) {registerConsumer(CircuitBreakerOnCallNotPermittedEvent.class, onCallNotPermittedEventConsumer);return this;}@Overridepublic void consumeEvent(CircuitBreakerEvent event) {super.processEvent(event);}}
复制代码
  • CircuitBreakerEventProcessor继承了EventProcessor,处理CircuitBreakerEvent事件
  • CircuitBreakerEventProcessor也实现了EventConsumer以及EventPublisher接口
  • onSuccess、onError、onStateTransition、onReset、onIgnoredError、onCallNotPermitted里头调用了registerConsumer方法
  • consumeEvent里头则是调用了processEvent方法

EventProcessor

resilience4j-core-0.13.0-sources.jar!/io/github/resilience4j/core/EventProcessor.java

public class EventProcessor<T> implements EventPublisher<T> {protected volatile boolean consumerRegistered;private volatile EventConsumer<T> onEventConsumer;private ConcurrentMap<Class<? extends T>, EventConsumer<Object>> eventConsumers = new ConcurrentHashMap<>();public boolean hasConsumers(){return consumerRegistered;}@SuppressWarnings("unchecked")public <E extends T> void registerConsumer(Class<? extends E> eventType, EventConsumer<E> eventConsumer){consumerRegistered = true;eventConsumers.put(eventType, (EventConsumer<Object>) eventConsumer);}@SuppressWarnings("unchecked")public <E extends T> boolean processEvent(E event) {boolean consumed = false;if(onEventConsumer != null){onEventConsumer.consumeEvent(event);consumed = true;}if(!eventConsumers.isEmpty()){EventConsumer<T> eventConsumer = (EventConsumer<T>) eventConsumers.get(event.getClass());if(eventConsumer != null){eventConsumer.consumeEvent(event);consumed = true;}}return consumed;}@Overridepublic void onEvent(EventConsumer<T> onEventConsumer) {consumerRegistered = true;this.onEventConsumer = onEventConsumer;}
}
复制代码
  • registerConsumer方法主要是往eventConsumers设置事件类型的消费者
  • processEvent方法主要是查找相应的事件消费者去处理事件

EventPublisher

resilience4j-circuitbreaker-0.13.0-sources.jar!/io/github/resilience4j/circuitbreaker/CircuitBreaker.java

    /*** An EventPublisher can be used to register event consumers.*/interface EventPublisher extends io.github.resilience4j.core.EventPublisher<CircuitBreakerEvent> {EventPublisher onSuccess(EventConsumer<CircuitBreakerOnSuccessEvent> eventConsumer);EventPublisher onError(EventConsumer<CircuitBreakerOnErrorEvent> eventConsumer);EventPublisher onStateTransition(EventConsumer<CircuitBreakerOnStateTransitionEvent> eventConsumer);EventPublisher onReset(EventConsumer<CircuitBreakerOnResetEvent> eventConsumer);EventPublisher onIgnoredError(EventConsumer<CircuitBreakerOnIgnoredErrorEvent> eventConsumer);EventPublisher onCallNotPermitted(EventConsumer<CircuitBreakerOnCallNotPermittedEvent> eventConsumer);}
复制代码
  • 这个EventPublisher接口继承了io.github.resilience4j.core.EventPublisher,逻辑上有点混乱
  • 这些on方法分别处理了CircuitBreakerOnSuccessEvent、CircuitBreakerOnErrorEvent、CircuitBreakerOnStateTransitionEvent、CircuitBreakerOnResetEvent、CircuitBreakerOnIgnoredErrorEvent、CircuitBreakerOnCallNotPermittedEvent事件

CircuitBreakerEvent

resilience4j-circuitbreaker-0.13.0-sources.jar!/io/github/resilience4j/circuitbreaker/event/CircuitBreakerEvent.java

/*** An event which is created by a CircuitBreaker.*/
public interface CircuitBreakerEvent {/*** Returns the name of the CircuitBreaker which has created the event.** @return the name of the CircuitBreaker which has created the event*/String getCircuitBreakerName();/*** Returns the type of the CircuitBreaker event.** @return the type of the CircuitBreaker event*/Type getEventType();/*** Returns the creation time of CircuitBreaker event.** @return the creation time of CircuitBreaker event*/ZonedDateTime getCreationTime();/*** Event types which are created by a CircuitBreaker.*/enum Type {/** A CircuitBreakerEvent which informs that an error has been recorded */ERROR(false),/** A CircuitBreakerEvent which informs that an error has been ignored */IGNORED_ERROR(false),/** A CircuitBreakerEvent which informs that a success has been recorded */SUCCESS(false),/** A CircuitBreakerEvent which informs that a call was not permitted because the CircuitBreaker state is OPEN */NOT_PERMITTED(false),/** A CircuitBreakerEvent which informs the state of the CircuitBreaker has been changed */STATE_TRANSITION(true),/** A CircuitBreakerEvent which informs the CircuitBreaker has been reset */RESET(true),/** A CircuitBreakerEvent which informs the CircuitBreaker has been forced open */FORCED_OPEN(false),/** A CircuitBreakerEvent which informs the CircuitBreaker has been disabled */DISABLED(false);public final boolean forcePublish;Type(boolean forcePublish) {this.forcePublish = forcePublish;}}
}
复制代码
  • CircuitBreakerEvent接口定义了事件的Type枚举
  • 规范了getCircuitBreakerName、getEventType、getCreationTime方法

AbstractCircuitBreakerEvent

resilience4j-circuitbreaker-0.13.0-sources.jar!/io/github/resilience4j/circuitbreaker/event/AbstractCircuitBreakerEvent.java

abstract class AbstractCircuitBreakerEvent implements CircuitBreakerEvent {private final String circuitBreakerName;private final ZonedDateTime creationTime;AbstractCircuitBreakerEvent(String circuitBreakerName) {this.circuitBreakerName = circuitBreakerName;this.creationTime = ZonedDateTime.now();}@Overridepublic String getCircuitBreakerName() {return circuitBreakerName;}@Overridepublic ZonedDateTime getCreationTime() {return creationTime;}
}
复制代码
  • 定义了circuitBreakerName、creationTime属性
  • 重写了getCircuitBreakerName、getCreationTime方法
  • ircuitBreakerOnSuccessEvent、CircuitBreakerOnErrorEvent、CircuitBreakerOnStateTransitionEvent、CircuitBreakerOnResetEvent、CircuitBreakerOnIgnoredErrorEvent、CircuitBreakerOnCallNotPermittedEvent都是从AbstractCircuitBreakerEvent继承而来,个别的自定义了自己的属性,主要是重写getEventType以及toString方法

小结

  • CircuitBreakerStateMachine里头维护了一个AtomicReference引用,对应的onError及onSuccess方法都委托给改引用对应的状态的onError以及onSuccess方法
  • 子类的onError以及onSuccess方法方法则自行判断是否需要进行状态切换以及切换到什么状态,自己调用CircuitBreakerStateMachine的transitionTo开头的方法,来改变AtomicReference的值(借助子类的各自实现来化解状态转换的复杂逻辑),同时发布一些事件。

doc

  • Resilience4j is a fault tolerance library designed for Java8 and functional programming

聊聊resilience4j的CircuitBreakerStateMachine相关推荐

  1. 聊聊resilience4j的bulkhead

    为什么80%的码农都做不了架构师?>>>    序 本文主要研究一下resilience4j的bulkhead Bulkhead resilience4j-bulkhead-0.13 ...

  2. 面向对象设计原则_聊聊面向对象的6大设计原则

    程序员都知道编程有 3 大类:面向过程.面向对象.面向函数.面向对象是被讨论的最多的,个人认为,这是因为 Java 之类的编程语言有强大的用户基础,本质还是因为比较符合人的直觉. 说到面向对象,大家可 ...

  3. python邮件发送哪个好_最全总结!聊聊 Python 发送邮件的几种方式

    1. 前言 邮件,作为最正式规范的沟通方式,在日常办公过程中经常被用到 我们都知道 Python内置了对 SMTP 的支持,可以发送纯文本.富文本.HTML 等格式的邮件 本文将聊聊利用 Python ...

  4. 今天聊聊分布式锁 No.86

    好了切入正题,一直在工作中会聊到很多锁的问题,今天跟大家一起闲聊一下,究竟什么是锁,为什么需要锁,以及分布式的情况下,怎么设计和实现锁. 什么是锁? 明·魏禧<大铁椎传>上是这样解释的: ...

  5. 聊聊找工作中的项目经验问题(推荐系统和智能问答)

    在求职过程中有这么一句话叫做"金九银十",也就是说,很多时候,求职的黄金时期就是在九月份和十月份,这两个月份中企业需求是最多的,求职的成功率也是最高的.但是随着AI方面的人才越来越 ...

  6. resilience4j小试牛刀

    为什么80%的码农都做不了架构师?>>>    序 本文主要研究下resilience4j的基本功能 maven <dependency><groupId>i ...

  7. 聊聊Service Mesh:linkerd

    [编者的话]随着企业逐渐将传统的单体应用向微服务或云原生应用的转变,虽然微服务或者云原生应用能给企业带来更多的好处,但也会带来一些具有挑战的问题,如怎么管理从单体应用转向微服务所带来的服务间通讯的复杂 ...

  8. 庖丁解牛迭代器,聊聊那些藏在幕后的秘密

    0x00 前言 \\ 在我之前的一篇博客<细说C#:不是"栈类型"的值类型,从生命周期聊存储位置>的最后,我以总结和后记的方式涉及到一部分迭代器的知识.但是觉得还是不够 ...

  9. 聊聊Unsafe的一些使用技巧

    记得初学 Java 那会,刚学完语法基础,就接触到了反射这个 Java 提供的特性,尽管在现在看来,这是非常基础的知识点,但那时候无疑是兴奋的,瞬间觉得自己脱离了"Java 初学者" ...

最新文章

  1. IT 学习资料 大全
  2. maven如何将本地jar安装到本地仓库
  3. 机场新增卫星厅对中转旅客影响的评估方法
  4. 【原创】Proton在Android上的编译
  5. Android7.1 Offload模式下的音频数据抽取过程
  6. pandas基础知识---4
  7. 如何用cocos2d-x来开发简单的Uphone游戏:(三) 射击子弹 碰撞检测
  8. 1.Series和DataFrame
  9. 查询2021高考成绩位次,2021年江苏高考位次表及高考个人成绩排名查询
  10. 防火墙与路由器的区别
  11. java 区分中英文_在java中如何判断一个字符串是中文的还是英文的
  12. 计算机显示没有可以的ip地址,电脑连不上WiFi,手机可以访问,出现黄色感叹号,没有有效的ip配置...
  13. 所谓的进步和提升,就是完成认知升级
  14. 电脑共享文件打不开要如何解决
  15. 腾讯视频会议真实内部实现分享
  16. js把汉字转换成拼音
  17. 情绪识别软件?论程序员对猫的偏爱!
  18. vscode美化插件推荐
  19. 解决ie浏览器el-select选择后出现光标的问题
  20. 北海道看雪(攻略及摄影)

热门文章

  1. SQL基础---SQL SELECT DISTINCT 语句
  2. 移植uboot第四步:设置NAND启动
  3. vue2.0 + element ui 实现表格穿梭框
  4. arcengine坐标转换[转]
  5. bat、sh等批处理文件(脚本文件)
  6. FZU 2087 统计树边【MST相关】
  7. 替换字符串空格 - Java - StringBuffer
  8. C# ICSharpCode.SharpZipLib.Zip 的使用
  9. 《黑马程序员》认识OC的第一个程序(Objective-c)
  10. 翻译关于ViewController的一篇文章