CircuitBreaker一共定义了6种Event
如果要使用事件,则必须注册事件使用者,如想在调用成功后执行某个操作,必须先注册CircuitBreakerOnSuccessEvent的消费者
circuitBreaker.getEventPublisher()
.onSuccess(event -> logger.info("调用成功"));
如果想所有事件都触发,可以注册通用消费者
circuitBreaker.getEventPublisher()
.onEvent(event -> logger.info("通用事件"));
继承 Core.EventPublisher ,是事件发布者接口,主要用于注册注册事件
/**
* An EventPublisher can be used to register event consumers.
* 事件处理器,用于向EventProcessor中注册处理六种事件的EventConsumer,且可根据不同事件类型注册不同的处理策略,onEvent默认所有事件触发
*/
interface EventPublisher extends
io.github.resilience4j.core.EventPublisher {
//请求成功时触发的事件消费策略
EventPublisher onSuccess(EventConsumer eventConsumer);
//请求失败时触发的事件消费策略
EventPublisher onError(EventConsumer eventConsumer);
//熔断状态发生变化时触发的事件消费策略
EventPublisher onStateTransition(
EventConsumer eventConsumer);
//熔断状态被重置触发的事件消费策略
EventPublisher onReset(EventConsumer eventConsumer);
//请求出现异常,但是是可忽略的异常时触发的事件消费策略
EventPublisher onIgnoredError(
EventConsumer eventConsumer);
//熔断开启请求不运行通过的事件消费策略
EventPublisher onCallNotPermitted(
EventConsumer eventConsumer);
}
具体由CircuitBreakerStateMachine.CircuitBreakerEventProcessor实现,即是消费者,也是发布者
//CircuitBreaker的事件处理器CircuitBreakerEventProcessor即是事件的发布者,同时也是事件的消费者
private class CircuitBreakerEventProcessor extends
EventProcessor implements EventConsumer,
EventPublisher {
//不同的事件类型创建不同的消费者
@Override
public EventPublisher onSuccess(
//创建CircuitBreakerOnSuccessEvent 消费者
//该事件类名就会作为EventProcessor类中用来存放消费者集合Map中的key,value即为创建的该event实例
EventConsumer onSuccessEventConsumer) {
//注册上面创建的消费者
registerConsumer(CircuitBreakerOnSuccessEvent.class.getSimpleName(),
onSuccessEventConsumer);
return this;
}
。。。。
}
关系如下:
EventConsumer: 事件消费者,是个函数式接口,只有一个consumeEvent()方法,定义消费的具体行为
//事件消费者接口(观察者)
@FunctionalInterface
public interface EventConsumer {
//用来处理T类型的事件
void consumeEvent(T event);
}
EventPublisher: 事件发布者,只有一个onEvent()方法,主要用来注册通用事件,即所有事件类型都会消费该event
public interface EventPublisher {
//用于设置处理T事件的消费者
void onEvent(EventConsumer onEventConsumer);
}
EventProcessor: 主要用来注册消费者和调用消费者消费
public class EventProcessor implements EventPublisher {
//用来存放通用事件消费者
List> onEventConsumers = new CopyOnWriteArrayList();
//用来存放定义的6种特定的CircuitBreakerEvent事件
//key:6种事件的类名,value:事件实例
ConcurrentMap>> 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 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> 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 onEventConsumer) {
this.consumerRegistered = true;
this.onEventConsumers.add(onEventConsumer);
}
}
以调用成功为例,在注册即往ConcurrentMap
注册消费者时this.registerConsumer(CircuitBreakerOnSuccessEvent.class.getSimpleName(), onSuccessEventConsumer);
指定了key为“CircuitBreakerOnSuccessEvent”,消费时先创建CircuitBreakerOnSuccessEvent事件,消费时就会获取创建的该事件的类名,去map中筛选List
这样就形成了一个闭环
不同的行为对应不同的行为实现和不同的事件,这部分代码实现思维很值得学习
创建circuitBreaker后,就可以使用得到EventPublisher 从而调用 ——> onSuccess进行注册 circuitBreaker.getEventPublisher().onSuccess(event -> log.error("消费成功") );
——>执行后端调用,成功获取信号量调用成功后,调用 ——>circuitBreaker.onSuccess()——>publishSuccessEvent()——>创建CircuitBreakerOnSuccessEvent事件 ——>CircuitBreakerEventProcessor.consumeEvent()——>EventProcessor.processEvent()消费事件