Resilience4j-----BulkHead

介绍

Bulkhead意指船舶中的隔舱板,它将船体分割为多个船舱,在船部分受损时可避免沉船。框架中的Bulkhead通过信号量的方式隔离不同种类的调用,并进行流控,这样可以避免某类调用异常危及系统整体。(注:不同于Hystrix,该框架不提供基于线程池的隔离)

初始化Bulkhead

Bulkhead的配置方式与熔断类似,有对应的BulkheadRegistry 和 BulkheadConfig,自定义配置的可选项有:

  1. 最大并行度
  2. 尝试进入饱和态的Bulkhead时,线程的最大阻塞时间

// 创建自定义的Bulkhead配置

BulkheadConfig config = BulkheadConfig.custom() .maxConcurrentCalls(150) .maxWaitTime(100) .build(); // 创建Bulkhead注册中心

BulkheadRegistry registry = BulkheadRegistry.of(config); // 从注册中心获取默认配置的Bulkhead

Bulkhead bulkhead1 = registry.bulkhead("foo"); // 从注册中心获取自定义配置的Bulkhead

Bulkhead bulkhead2 = registry.bulkhead("bar", config);

你也可以不经过注册中心,直接创建Bulkhead:

Bulkhead bulkhead1 = Bulkhead.ofDefaults("foo");

Bulkhead bulkhead2 = Bulkhead.of( "bar", BulkheadConfig.custom() .maxConcurrentCalls(50) .build() );

Bulkhead使用方式

与熔断类似,不再赘述,下面是代码示例:

// 创建Bulkhead实例

Bulkhead bulkhead = Bulkhead.of("testName", config);

// 用Bulkhead包装函数调用

CheckedFunction0<String> decoratedSupplier = Bulkhead.decorateCheckedSupplier(bulkhead, () -> "This can be any method which returns: 'Hello");

// 链接其它函数

Try<String> result = Try.of(decoratedSupplier) .map(value -> value + " world'");

assertThat(result.isSuccess()).isTrue();

assertThat(result.get()).isEqualTo("This can be any method which returns: 'Hello world'");

assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(1);

函数链中可以包含被不同Bulkhead或熔断器包装的多个函数:

// 两个Bulkhead

Bulkhead bulkhead = Bulkhead.of("test", config);

Bulkhead anotherBulkhead = Bulkhead.of("testAnother", config);

// 用两个Bulkhead分别包装Supplier 和 Function

CheckedFunction0<String> decoratedSupplier = Bulkhead.decorateCheckedSupplier(bulkhead, () -> "Hello");

CheckedFunction1<String, String> decoratedFunction = Bulkhead.decorateCheckedFunction(anotherBulkhead, (input) -> input + " world");

// 链接函数

Try<String> result = Try.of(decoratedSupplier) .mapTry(decoratedFunction::apply);

assertThat(result.isSuccess()).isTrue();

assertThat(result.get()).isEqualTo("Hello world");

assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(1);

assertThat(anotherBulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(1);

下面我们模拟饱和态Bulkhead的行为:

// 创建并行度为2的Bulkhead

BulkheadConfig config = BulkheadConfig.custom().maxConcurrentCalls(2).build();

Bulkhead bulkhead = Bulkhead.of("test", config);

// 该方法会进入Bulkhead

bulkhead.isCallPermitted();

bulkhead.isCallPermitted();

// 经过上面两次调用,Bulkhead已饱和

CheckedRunnable checkedRunnable = Bulkhead.decorateCheckedRunnable(bulkhead, () -> {throw new RuntimeException("BAM!");});

Try result = Try.run(checkedRunnable);

assertThat(result.isFailure()).isTrue();

assertThat(result.failed().get()).isInstanceOf(BulkheadFullException.class);

你可以在运行时动态修改Bulkhead配置,但新的最大阻塞时间不会影响当前正在等待的线程。

与熔断类似,Bulkhead也支持RxJava/Reactor.

Bulkhead bulkhead = Bulkhead.ofDefaults("backendName");

Observable.fromCallable(backendService::doSomething) .lift(BulkheadOperator.of(bulkhead));

Bulkhead bulkhead = Bulkhead.ofDefaults("backendName");

Mono.fromCallable(backendService::doSomething) .transform(BulkheadOperator.of(bulkhead));

监听Bulkhead事件

BulkHeadEvent包含允许执行、拒绝执行、执行结束事件,可以用如下方式监听:

bulkhead.getEventPublisher() .onCallPermitted(event -> logger.info(...)) .onCallRejected(event -> logger.info(...)) .onCallFinished(event -> logger.info(...));

Bulkhead状态

Bulkhead.Metrics metrics = bulkhead.getMetrics();

in remainingBulkheadDepth = metrics.getAvailableConcurrentCalls()

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值