resilience4j之CircuitBreaker熔断器——CircuitBreakerEvent 事件


   Resilience4j 框架的一大亮点 就是实现了基于事件驱动的架构设计,所以我认为事件注册和发布这部分值得好好学习,希望下面相应解释可以帮助您的理解

一: CircuitBreakerEvent

CircuitBreaker一共定义了6种Event
在这里插入图片描述
在这里插入图片描述如果要使用事件,则必须注册事件使用者,如想在调用成功后执行某个操作,必须先注册CircuitBreakerOnSuccessEvent的消费者

circuitBreaker.getEventPublisher()
    .onSuccess(event -> logger.info("调用成功"));

如果想所有事件都触发,可以注册通用消费者

circuitBreaker.getEventPublisher()
    .onEvent(event -> logger.info("通用事件"));

二: CircuitBreaker.EventPublisher 事件

继承 Core.EventPublisher ,是事件发布者接口,主要用于注册注册事件

    /**
     * An EventPublisher can be used to register event consumers.
     * 事件处理器,用于向EventProcessor中注册处理六种事件的EventConsumer,且可根据不同事件类型注册不同的处理策略,onEvent默认所有事件触发
     */
    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);
    }

具体由CircuitBreakerStateMachine.CircuitBreakerEventProcessor实现,即是消费者,也是发布者

    //CircuitBreaker的事件处理器CircuitBreakerEventProcessor即是事件的发布者,同时也是事件的消费者
    private class CircuitBreakerEventProcessor extends
        EventProcessor<CircuitBreakerEvent> implements EventConsumer<CircuitBreakerEvent>,
        EventPublisher {

		//不同的事件类型创建不同的消费者
        @Override
        public EventPublisher onSuccess(
           //创建CircuitBreakerOnSuccessEvent 消费者
           //该事件类名就会作为EventProcessor类中用来存放消费者集合Map中的key,value即为创建的该event实例
            EventConsumer<CircuitBreakerOnSuccessEvent> onSuccessEventConsumer) {
            //注册上面创建的消费者
            registerConsumer(CircuitBreakerOnSuccessEvent.class.getSimpleName(),
                onSuccessEventConsumer);
            return this;
        }
	 。。。。
	}

关系如下:
在这里插入图片描述
EventConsumer: 事件消费者,是个函数式接口,只有一个consumeEvent()方法,定义消费的具体行为

//事件消费者接口(观察者)
@FunctionalInterface
public interface EventConsumer<T> {
    //用来处理T类型的事件
    void consumeEvent(T event);
}

EventPublisher: 事件发布者,只有一个onEvent()方法,主要用来注册通用事件,即所有事件类型都会消费该event

public interface EventPublisher<T> {
    //用于设置处理T事件的消费者
    void onEvent(EventConsumer<T> onEventConsumer);
}

EventProcessor: 主要用来注册消费者和调用消费者消费

public class EventProcessor<T> implements EventPublisher<T> {
	//用来存放通用事件消费者
    List<EventConsumer<T>> onEventConsumers = new CopyOnWriteArrayList();
    //用来存放定义的6种特定的CircuitBreakerEvent事件
    //key:6种事件的类名,value:事件实例
    ConcurrentMap<String, List<EventConsumer<T>>> eventConsumerMap = new ConcurrentHashMap();
    private boolean consumerRegistered;

    public EventProcessor() {
    }

    public boolean hasConsumers() {
        return this.consumerRegistered;
    }

   //注册事件
   //key:6种事件的类名,如CircuitBreakerOnSuccessEvent、CircuitBreakerOnErrorEvent等
   //value:具体的消费者实例
   //CircuitBreakerEventProcessor.onSuccess()等定义的6种事件调用
    public synchronized void registerConsumer(String className, EventConsumer<? extends T> eventConsumer) {
        this.consumerRegistered = true;
        this.eventConsumerMap.compute(className, (k, consumers) -> {
            if (consumers == null) {
                List consumersx = new ArrayList();
                consumersx.add(eventConsumer);
                return consumersx;
            } else {
                consumers.add(eventConsumer);
                return consumers;
            }
        });
    }

    //调用消费者消费事件,返回true 已处理,false未处理
    public <E extends T> boolean processEvent(E event) {
        boolean consumed = false;

		// 通用消费者消费事件
        if (!this.onEventConsumers.isEmpty()) {
            this.onEventConsumers.forEach((onEventConsumer) -> {
                onEventConsumer.consumeEvent(event);
            });
            consumed = true;
        }

		// 特定消费者消费事件
        if (!this.eventConsumerMap.isEmpty()) {
             //*** 从注册的消费者中筛选符合类型的消费者
             //即筛选key为指定事件的类名的消费者,如CircuitBreakerOnSuccessEvent
            List<EventConsumer<T>> eventConsumers = (List)this.eventConsumerMap.get(event.getClass().getSimpleName());
            if (eventConsumers != null && !eventConsumers.isEmpty()) {
                eventConsumers.forEach((consumer) -> {
                   //***调用消费者消费事件
                    consumer.consumeEvent(event);
                });
                consumed = true;
            }
        }

        return consumed;
    }

    //用来注册通用事件
    public synchronized void onEvent(@Nullable EventConsumer<T> onEventConsumer) {
        this.consumerRegistered = true;
        this.onEventConsumers.add(onEventConsumer);
    }
}

三: 消费注册是如何实现的

以调用成功为例,在注册即往ConcurrentMap<String, List<EventConsumer<T>>> eventConsumerMap = new ConcurrentHashMap()注册消费者时this.registerConsumer(CircuitBreakerOnSuccessEvent.class.getSimpleName(), onSuccessEventConsumer); 指定了key为“CircuitBreakerOnSuccessEvent”,消费时先创建CircuitBreakerOnSuccessEvent事件,消费时就会获取创建的该事件的类名,去map中筛选List<EventConsumer<T>> eventConsumers = this.eventConsumerMap .get(event.getClass().getSimpleName()); 这样就形成了一个闭环

不同的行为对应不同的行为实现和不同的事件,这部分代码实现思维很值得学习

四: 梳理调用关系

创建circuitBreaker后,就可以使用得到EventPublisher 从而调用 ——> onSuccess进行注册 circuitBreaker.getEventPublisher().onSuccess(event -> log.error("消费成功") ); ——>执行后端调用,成功获取信号量调用成功后,调用 ——>circuitBreaker.onSuccess()——>publishSuccessEvent()——>创建CircuitBreakerOnSuccessEvent事件 ——>CircuitBreakerEventProcessor.consumeEvent()——>EventProcessor.processEvent()消费事件

Resilience4j 是一个用于构建弹性和容错性应用程序的轻量级库,其中包括熔断器(Circuit Breaker)功能。下面是 Resilience4j 熔断器的简单使用方法: 1. 添加 Maven 依赖:在项目的 pom.xml 文件中添加以下 Maven 依赖: ```xml <dependency> <groupId>io.github.resilience4j</groupId> <artifactId>resilience4j-circuitbreaker</artifactId> <version>1.7.0</version> </dependency> ``` 2. 创建熔断器实例:使用 CircuitBreakerRegistry 创建一个熔断器实例。 ```java CircuitBreakerConfig config = CircuitBreakerConfig.custom() .failureRateThreshold(50) // 失败率阈值 .waitDurationInOpenState(Duration.ofMillis(1000)) // 熔断器打开后等待时间 .ringBufferSizeInHalfOpenState(2) // 半开状态下环形缓冲区大小 .ringBufferSizeInClosedState(2) // 关闭状态下环形缓冲区大小 .build(); CircuitBreakerRegistry registry = CircuitBreakerRegistry.of(config); CircuitBreaker circuitBreaker = registry.circuitBreaker("myCircuitBreaker"); ``` 3. 包装方法调用:使用熔断器包装需要进行容错处理的方法调用。 ```java CircuitBreaker.decorateCheckedSupplier(circuitBreaker, () -> { // 调用需要容错处理的方法 return myService.doSomething(); }); ``` 4. 处理熔断器状态:根据熔断器的状态进行相应处理。 ```java if (circuitBreaker.getState() == CircuitBreaker.State.OPEN) { // 熔断器打开时的处理逻辑 // 例如,返回一个默认值或者抛出一个自定义异常 } else { // 熔断器关闭或半开时的处理逻辑 // 例如,正常执行业务逻辑 } ``` 上述步骤中,你可以根据实际需求配置熔断器的参数,如失败率阈值、等待时间、环形缓冲区大小等。通过包装方法调用,当方法调用失败或达到一定条件时,熔断器将会打开,并执行相应的容错逻辑。你可以根据熔断器的状态来处理不同的情况。 注意:上述代码片段仅为示例,你需要根据自己的业务需求进行适当的调整和配置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值