Bulkhead

resilience4j-SpringBoot2-demo

Bulkhead中文意思:船舶中的隔舱板,将船体分割成多个船舱。把应用系统当成一艘船,那么应用中不同方法,就对应船里面不同船舱,船舱可能是单人间,也可能是四人间、八人间、或者大通铺。船舱容量对应应用中不同方法允许承受的最大并发量。Bulkhead作用是让一个应用中不同方法互不影响,避免某些方法调用异常危及整个应用。

主要分为以下几个模块:隔离器配置,隔离器注册,隔离器事件消费者注册,隔离器状态及指标,隔离器事件,隔离器事件处理器,隔离器事件消费者。

各模块间关系

 

  • BulkheadRegistry通过其实现类InMemoryBulkheadRegistry根据BulkheadConfig创建Bulkhead实例。
  • EventConsumerRegistry通过其实现类DefaultEventConsumerRegistry创建EventConsumer事件消费者。
  • Bulkhead通过其实现类SemaphoreBulkhead控制并发,并发布BulkheadEvent从而被注册到EventProcessor事件处理器的EventConsumer事件消费者消费。

Bulkhead接口介绍

通过下图可看出主要依次分为一下几个部分:

  • 动态改变隔离配置
  • 隔离请求判断&完成时操作 (隔离器最核心流程)
  • 获取对应隔离信息
  • 装饰器模式提供多个接口、支持lambda表达式。
  • 度量指标
  • 事件发布&注册

 

核心配置

  • maxConcurrentCalls : Bulkhead允许的最大并行执行量。默认:25
  • maxWaitDuration:尝试进入饱和舱壁时线程阻塞等待的最长时间。默认:0

核心流程图

Bulkhead核心处理流程如下所示,当请求被拒绝时,抛出BulkheadFullException。并在请求通过、拒绝、完成时,publish 对应 BulkheadEvent。
本文主要讲述SemaphoreBulkhead信号量隔离机制,最新版本新增支持了ThreadPoolBulkhead。

 

BulkheadEvent

隔离器事件,有三种类型。

/** 请求被允许通过时,发布.*/
CALL_PERMITTED
/** 请求被允许拒绝时,发布*/
CALL_REJECTED,
/** 处理请求后发布,无论请求是通过还是被拒绝*/
CALL_FINISHED;

SemaphoreBulkhead

Bulkhead接口实现类,利用JDK的Semaphore实现并发控制。

从图中其构造方法可看出,使用的是Semaphore公平模式,即先到先得。
 

isCallPermitted

public boolean isCallPermitted() {
    //尝试获取信号量,并返回结果
    boolean callPermitted = tryEnterBulkhead();
    //根据获取结果发布对应event
    publishBulkheadEvent(
            () -> callPermitted ? new BulkheadOnCallPermittedEvent(name)
                    : new BulkheadOnCallRejectedEvent(name)
    );

    return callPermitted;
}

boolean tryEnterBulkhead() {

    boolean callPermitted = false;
    //获取配置的最大等待时长
    long timeout = config.getMaxWaitTime();

    if (timeout == 0) {
        //直接尝试获取许可
        callPermitted = semaphore.tryAcquire();
    } else {
        try {
           //在对应规定时间内尝试获取许可
            callPermitted = semaphore.tryAcquire(timeout, TimeUnit.MILLISECONDS);
        } catch (InterruptedException ex) {
            callPermitted = false;
        }
    }
    return callPermitted;
}

semaphore.tryAcquire在Semaphore介绍中有介绍,这里不在叙述。

订阅消费事件和前面章节CircuitBreaker事件消费类似,不在叙述。

总结:

  • Bulkhead通过JDK中Semaphore(公平模式)实现并发控制。
  • 可在运行时修改Bulkhead配置,同时也可订阅对应事件。
  • Bulkhead是通过抛出BulkheadFullException方式终止请求调用的。