Spring Boot Reactor 整合 Resilience4j详析

目录
  • 1 引入 pom 包
  • 2 配置说明
    • 2.1 限流 ratelimiter
    • 2.2 重试 retry
    • 2.3 超时 TimeLimiter
    • 2.4 断路器 circuitbreaker
    • 2.5 壁仓 bulkhead
      • 2.5.1 SemaphoreBulkhead
      • 2.5.2 FixedThreadPoolBulkhead
  • 3 使用
    • 3.1 配置
    • 3.2 使用注解实现

1 引入 pom 包

<dependency>
    <groupId>io.github.resilience4j</groupId>
    <artifactId>resilience4j-all</artifactId>
</dependency>
<dependency>
    <groupId>io.github.resilience4j</groupId>
    <artifactId>resilience4j-spring-boot2</artifactId>
</dependency>

2 配置说明

2.1 限流 ratelimiter

两个限流配置:backendA 1s 中最多允许 10 次请求;

backendB 每 500ms 最多允许 6 次请求。

resilience4j.ratelimiter:
  instances:
    backendA:
      limitForPeriod: 10
      limitRefreshPeriod: 1s
      timeoutDuration: 10ms
      registerHealthIndicator: true
      eventConsumerBufferSize: 100
    backendB:
      limitForPeriod: 6
      limitRefreshPeriod: 500ms
      timeoutDuration: 3s
配置属性 默认值 描述
timeoutDuration 5【s】 一个线程等待许可的默认等待时间
limitRefreshPeriod 500【ns】 限制刷新的周期。在每个周期之后,速率限制器将其权限计数设置回 limitForPeriod 值
limitForPeriod 50 一个 limitRefreshPeriod (周期)允许访问的数量(许可数量)

2.2 重试 retry

注意指定需要重试的异常,不是所有的异常重试都有效。比如 DB 相关校验异常,如唯一约束等,重试也不会成功的。

重试配置:

resilience4j.retry:
  instances:
    backendA:
      maxAttempts: 3
      waitDuration: 10s
      enableExponentialBackoff: true
      exponentialBackoffMultiplier: 2
      retryExceptions:
        - org.springframework.web.client.HttpServerErrorException
        - java.io.IOException

    backendB:
      maxAttempts: 3
      waitDuration: 10s
      retryExceptions:
        - org.springframework.web.client.HttpServerErrorException
        - java.io.IOException
配置属性 默认值 描述
maxAttempts 3 最大重试次数(包括第一次)
waitDuration 500【ms】 两次重试之间的等待间隔
intervalFunction numOfAttempts -> waitDuration 修改失败后等待间隔的函数。默认情况下,等待时间是个常量。
retryOnResultPredicate result->false 配置一个判断结果是否应该重试的 predicate 函数。如果结果应该重试,Predicate 必须返回 true,否则它必须返回 false。
retryExceptionPredicate throwable -> true 和 retryOnResultPredicate 类似,如果要重试,Predicate 必须返回true,否则返回 false。
retryExceptions 需要重试的异常类型列表
ignoreExceptions 不需要重试的异常类型列表
failAfterMaxAttempts false 当重试达到配置的 maxAttempts 并且结果仍未通过 retryOnResultPredicate 时启用或禁用抛出 MaxRetriesExceededException 的布尔值
intervalBiFunction (numOfAttempts, Either<throwable, result>) -> waitDuration 根据 maxAttempts 和结果或异常修改失败后等待间隔时间的函数。与 intervalFunction 一起使用时会抛出 IllegalStateException。

2.3 超时 TimeLimiter

超时配置:

resilience4j.timelimiter:
  instances:
    backendA:
      timeoutDuration: 2s
      cancelRunningFuture: true
    backendB:
      timeoutDuration: 1s
      cancelRunningFuture: false

超时配置比较简单,主要是配置 timeoutDuration 也就是超时的时间。

cancelRunningFuture 的意思是:是否应该在运行的 Future 调用 cancel 去掉调用。

2.4 断路器 circuitbreaker

断路器有几种状态:关闭、打开、半开。注意:打开,意味着不能访问,会迅速失败。

CircuitBreaker 使用滑动窗口来存储和汇总调用结果。您可以在基于计数的滑动窗口和基于时间的滑动窗口之间进行选择。基于计数的滑动窗口聚合最后 N 次调用的结果。基于时间的滑动窗口聚合了最后 N 秒的调用结果。

断路器配置:

resilience4j.circuitbreaker:
  instances:
    backendA:
      // 健康指标参数,非断路器属性
      registerHealthIndicator: true
      slidingWindowSize: 100
配置属性 默认值 描述
slidingWindowSize 100 记录断路器关闭状态下(可以访问的情况下)的调用的滑动窗口大小
failureRateThreshold 50(百分比) 当失败比例超过 failureRateThreshold 的时候,断路器会打开,并开始短路呼叫
slowCallDurationThreshold 60000【ms】 请求被定义为慢请求的阈值
slowCallRateThreshold 100(百分比) 慢请求百分比大于等于该值时,打开断路器开关
permittedNumberOfCalls 10 半开状态下允许通过的请求数
maxWaitDurationInHalfOpenState 0 配置最大等待持续时间,该持续时间控制断路器在切换到打开之前可以保持在半开状态的最长时间。

值 0 表示断路器将在 HalfOpen 状态下无限等待,直到所有允许的调用都已完成。

2.5 壁仓 bulkhead

resilience4j 提供了两种实现壁仓的方法:

  • SemaphoreBulkhead 使用 Semaphore 实现
  • FixedThreadPoolBulkhead 使用有界队列和固定线程池实现
resilience4j.bulkhead:
  instances:
    backendA:
      maxConcurrentCalls: 10
    backendB:
      maxWaitDuration: 10ms
      maxConcurrentCalls: 20

resilience4j.thread-pool-bulkhead:
  instances:
    backendC:
      maxThreadPoolSize: 1
      coreThreadPoolSize: 1
      queueCapacity: 1

2.5.1 SemaphoreBulkhead

配置属性 默认值 描述
maxConcurrentCalls 25 允许的并发执行的数量
maxWaitDuration 0 尝试进入饱和隔板时线程应被阻止的最长时间

2.5.2 FixedThreadPoolBulkhead

配置属性 默认值 描述
maxThreadPoolSize Runtime.getRuntime().availableProcessors() 线程池最大线程个数
coreThreadPoolSize Runtime.getRuntime().availableProcessors()-1 线程池核心线程个数
queueCapacity 100 线程池队列容量
keepAliveDuration 20【ms】 线程数超过核心线程数之后,空余线程在终止之前等待的最长时间

3 使用

3.1 配置

在 application.yml 文件中添加以下 resilience4j 配置:

resilience4j.circuitbreaker:
  instances:
    backendA:
      registerHealthIndicator: true
      slidingWindowSize: 100

resilience4j.retry:
  instances:
    backendA:
      maxAttempts: 3
      waitDuration: 10s
      enableExponentialBackoff: true
      exponentialBackoffMultiplier: 2
      retryExceptions:
        - org.springframework.web.client.HttpServerErrorException
        - java.io.IOException

    backendB:
      maxAttempts: 3
      waitDuration: 10s
      retryExceptions:
        - org.springframework.web.client.HttpServerErrorException
        - java.io.IOException

resilience4j.bulkhead:
  instances:
    backendA:
      maxConcurrentCalls: 10
    backendB:
      maxWaitDuration: 10ms
      maxConcurrentCalls: 20

resilience4j.thread-pool-bulkhead:
  instances:
    backendC:
      maxThreadPoolSize: 1
      coreThreadPoolSize: 1
      queueCapacity: 1

resilience4j.ratelimiter:
  instances:
    backendA:
      limitForPeriod: 10
      limitRefreshPeriod: 1s
      timeoutDuration: 10ms
      registerHealthIndicator: true
      eventConsumerBufferSize: 100
    backendB:
      limitForPeriod: 6
      limitRefreshPeriod: 500ms
      timeoutDuration: 3s

resilience4j.timelimiter:
  instances:
    backendA:
      timeoutDuration: 2s
      cancelRunningFuture: true
    backendB:
      timeoutDuration: 1s
      cancelRunningFuture: false

3.2 使用注解实现

直接在需要限流的方法上增加注解@RateLimiter 实现限流;增加注解@Retry 实现重试;增加注解 @CircuitBreaker 熔断;增加注解 @Bulkhead 实现壁仓。name 属性中分别填写限流器、重试、熔断、壁仓组件的名字。

@Bulkhead(name = "backendA")
@CircuitBreaker(name = "backendA")
@Retry(name = "backendA")
@RateLimiter(name = "backendA")
public Mono<List<User>> list() {
  long startTime = System.currentTimeMillis();
  return Mono.fromSupplier(() -> {
        return userRepository.findAll();
      }).doOnError(e -> {
        // 打印异常日志&增加监控(自行处理)
        logger.error("list.user.error, e", e);
      })
      .doFinally(e -> {
        // 耗时 & 整体健康
        logger.info("list.user.time={}, ", System.currentTimeMillis() - startTime);
      });
}

@Bulkhead(name = "backendA")
@CircuitBreaker(name = "backendA")//最多支持10个并发量
@Retry(name = "backendA")//使用 backendA 重试器,如果抛出 IOException 会重试三次。
@RateLimiter(name = "backendA")// 限流 10 Qps
public Mono<Boolean> save(User user) {
  long startTime = System.currentTimeMillis();
  return Mono.fromSupplier(() -> {
        return userRepository.save(user) != null;
      })
      .doOnError(e -> {
        // 打印异常日志&增加监控(自行处理)
        logger.error("save.user.error, user={}, e", user, e);
      })
      .doFinally(e -> {
        // 耗时 & 整体健康
        logger.info("save.user.time={}, user={}", user, System.currentTimeMillis() - startTime);
      });
}

注意:以上所有组件,都支持自定义。

到此这篇关于Spring Boot Reactor 整合 Resilience4j详析的文章就介绍到这了,更多相关Spring Boot Reactor 内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java反应式框架Reactor中的Mono和Flux

    1. 前言 最近写关于响应式编程的东西有点多,很多同学反映对Flux和Mono这两个Reactor中的概念有点懵逼.但是目前Java响应式编程中我们对这两个对象的接触又最多,诸如Spring WebFlux.RSocket.R2DBC.我开始也对这两个对象头疼,所以今天我们就简单来探讨一下它们. 2. 响应流的特点 要搞清楚这两个概念,必须说一下响应流规范.它是响应式编程的基石.他具有以下特点: 响应流必须是无阻塞的.响应流必须是一个数据流.它必须可以异步执行.并且它也应该能够处理背压. 背压是

  • Reactor中的onErrorContinue 和 onErrorResume

    目录 前言 1 基础功能 2 只有 onErrorResume () 3 只有 onErrorContinue() 4 onErrorResume() 然后 onErrorContinue() 5 使用 onErrorResume() 模拟 onErrorContinue() 6 使用 onErrorResume() 和下游的 onErrorContinue() 模拟 onErrorContinue() 前言 这似乎是 Reactor 的热门搜索之一,至少当我在谷歌中输入 onErrorCont

  • Project Reactor源码解析publishOn使用示例

    目录 功能分析 代码示例 prefetch delayError 源码分析 Flux#publishOn() Flux#subscribe() FluxPublishOn#subscribeOrReturn() FluxPublishOn#onSubscribe() 非融合 FluxPublishOn#onNext() FluxPublishOn#trySchedule() FluxPublishOn#run() FluxPublishOn#runAsync() FluxPublishOn#ch

  • C++中的Reactor原理与实现

    目录 一.Reactor介绍 二.代码实现 一.Reactor介绍 reactor设计模式是event-driven architecture的一种实现方式,处理多个客户端并发的向服务端请求服务的场景.每种服务在服务端可能由多个方法组成.reactor会解耦并发请求的服务并分发给对应的事件处理器来处理. 中心思想是将所有要处理的I/o事件注册到一个中心I/o多路复用器上,同时主线程/进程阻塞在多路复用器上;一旦有I/o事件到来或是准备就绪(文件描述符或socket可读.写),多路复用器返回并将事

  • C#程序加密工具.Net Reactor详细教程

    .NET具有较多的优点,如:标准集成,简化应用,对移动设备的支持等.但使用.NET编写的程序有个致命的缺点:易被反编译,且运行时占用较大的资源. 那么我们就需要用到加密工具 dotNET Reactor 是一款强大的 .NET 代码保护和授权管理系统,安全可靠.简单易用,主要用来帮助开发人员保护他们的 .NET 软件产品.开发人员从此不必担心如何保护他们的知识产权,可以将更多精力放在产品功能的开发上.与代码混淆工具(Obfuscator)相比,.NET Reactor 可以完全阻止对 .NET

  • 用ASP开发网页需要牢记的注意事项

    步 骤 1.永远不要相信用户输入的内容具有适当的大小或者包含适当的字符.在使用其做出决策之前应该始终对用户输入进行验证.最佳的选择是创建一个 COM+ 组件,这样您可以从 ASP 页面中调用该组件来验证用户的输入内容.您也可以使用 Server.HTMLEncode 方法.Server.URLEncode 方法,或者本页底部代码示例中的某一个. 2.不要通过连接用户输入的字符串来创建 ASP 页中的数据库连接字符串.恶意用户可以通过在他们的输入内容中插入代码来获取数据库的访问权限.如果您使用的是

  • Java中多线程Reactor模式的实现

    目录 1. 主服务器 2.IO请求handler+线程池 3.客户端 多线程Reactor模式旨在分配多个reactor每一个reactor独立拥有一个selector,在网络通信中大体设计为负责连接的主Reactor,其中在主Reactor的run函数中若selector检测到了连接事件的发生则dispatch该事件. 让负责管理连接的Handler处理连接,其中在这个负责连接的Handler处理器中创建子Handler用以处理IO请求.这样一来连接请求与IO请求分开执行提高通道的并发量.同时

  • Reactor反应器的实现方法详解

    大多数应用都会使用ACE_Reactor::instance()提供的默认反应器实例.但是你也可以选择自己的反应器,这是因为ACE使用了Bridge模式(使用两个不同的类:一个是编程接口,另一个是实现,第一个类会把各个操作传给第二个类).例如使用线程池反应器实现:ACE_TP_Reactor* tp_reactor = new ACE_TP_Reactor;ACE_Reactor* my_reactor = new ACE_Reactor(tp_reactor, 1);//1表示my_react

  • Spring Boot 整合 Reactor实例详解

    目录 引言 1 创建项目 2 集成 H2 数据库 3 创建测试类 3.1 user 实体 3.2 UserRepository 3.3 UserService 3.4 UserController 3.5 SpringReactorApplication 添加注解支持 测试 总结 引言 Reactor 是一个完全非阻塞的 JVM 响应式编程基础,有着高效的需求管理(背压的形式).它直接整合 Java8 的函数式 API,尤其是 CompletableFuture, Stream,还有 Durat

  • Spring Boot Reactor 整合 Resilience4j详析

    目录 1 引入 pom 包 2 配置说明 2.1 限流 ratelimiter 2.2 重试 retry 2.3 超时 TimeLimiter 2.4 断路器 circuitbreaker 2.5 壁仓 bulkhead 2.5.1 SemaphoreBulkhead 2.5.2 FixedThreadPoolBulkhead 3 使用 3.1 配置 3.2 使用注解实现 1 引入 pom 包 <dependency> <groupId>io.github.resilience4j

  • 关于Spring Boot WebSocket整合以及nginx配置详解

    前言 本文主要给大家介绍了关于Spring Boot WebSocket整合及nginx配置的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 一:Spring Boot WebSocket整合 创建一个maven项目,加入如下依赖 <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId>

  • Spring Boot + Kotlin整合MyBatis的方法教程

    前言 最近使用jpa比较多,再看看mybatis的xml方式写sql觉得不爽,接口定义与映射离散在不同文件中,使得阅读起来并不是特别方便. 因此使用Spring Boot去整合MyBatis,在注解里写sql 参考<我的第一个Kotlin应用> 创建项目,在build.gradle文件中引入依赖 compile "org.mybatis.spring.boot:mybatis-spring-boot-starter:$mybatis_version" compile &qu

  • Spring Boot Admin的使用详解(Actuator监控接口)

    第一部分 Spring Boot Admin 简介 Spring Boot Admin用来管理和监控Spring Boot应用程序. 应用程序向我们的Spring Boot Admin Client注册(通过HTTP)或使用SpringCloud®(例如Eureka,Consul)发现. UI是Spring Boot Actuator端点上的Vue.js应用程序. Spring Boot Admin 是一个管理和监控Spring Boot 应用程序的开源软件.每个应用都认为是一个客户端,通过HT

  • Java Spring Boot消息服务万字详解分析

    目录 消息服务概述 为什么要使用消息服务 异步处理 应用解耦 流量削峰 分布式事务管理 常用消息中间件介绍 ActiveMQ RabbitMQ RocketMQ RabbitMQ消息中间件 RabbitMQ简介 RabbitMQ工作模式介绍 Work queues(工作队列模式) Public/Subscribe(发布订阅模式) Routing(路由模式) Topics(通配符模式) RPC Headers RabbitMQ安装以及整合环境搭建 安装RabbitMQ 下载RabbitMQ 安装R

  • Spring boot 使用mysql实例详解

    Spring boot 使用mysql实例详解 开发阶段用 H2即可,上线时,通过以下配置切换到mysql,spring boot将使用这个配置覆盖默认的H2. 1.建立数据库: mysql -u root CREATE DATABASE springbootdb 2.pom.xml: <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId&g

  • Spring boot怎么整合Mybatis

    最近刚接触spring boot,正是因为他的及简配置方便开发,促使我下定决心要用它把之前写的项目重构,那么问题来了,spring boot怎么整合mybatis呢,下面几个配置类来搞定. 在我的代码当中是实现了数据库读写分离的,所以代码仅做参考,如有需要可以加我微信:benyzhous [后续更新] 1.文件结构 DataBaseConfiguration.Java用来获取数据库连接配置信息,配置从application.properties中读取 MybatisConfiguration.j

  • Dubbo在Spring和Spring Boot中的使用详解

    一.在Spring中使用Dubbo 1.Maven依赖 <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.5.3.6</version> <exclusions> <exclusion> <groupId>log4j</groupId> <artif

  • Spring Boot 集成MyBatis 教程详解

    Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置.通过这种方式,Spring Boot致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者. 在集成MyBatis前,我们先配置一个druid数据源. Spring Boot 系列 1.Spring Boot 入门 2.Spring Boot 属性配置

  • spring boot linux启动方式详解

    前台启动 java -jar XXX.jar 后台启动 java -jar xxx.jar & 区别:前台启动ctrl+c就会关闭程序,后台启动ctrl+c不会关闭程序 制定控制台的标准输出 java -jar xxx.jar > catalina.out 2>&1 & catalina.out将标准输出指向制定文件catalina.out 2>&1 输出所有的日志文件 & 后台启动  脚本启动 #!/bin/sh #功能简介:启动上层目录下的ja

随机推荐