Spring Boot 中使用 Resilience4j 实现弹性微服务的简单了解

1. 引言

在微服务架构中,服务的弹性是非常重要的。Resilience4j 是一个轻量级的容错库,专为函数式编程设计,提供了断路器、重试、舱壁、限流器和限时器等功能。

这里不做过多演示,只是查看一下官方案例并换成maven构建相关展示;

2.配置

spring:
  application.name: resilience4j-demo
  jackson.serialization.indent_output: true # 格式化输出json

server:
  port: 9080

management.endpoints.web.exposure.include: '*' # 暴露所有端点
management.endpoint.health.show-details: always # 显示详细健康信息

management.health.diskspace.enabled: false # 关闭磁盘空间健康检查
management.health.db.enabled: false # 关闭数据库健康检查
management.health.circuitbreakers.enabled: true #  开启断路器健康检查
management.health.conditions.enabled: false # 关闭条件健康检查
management.health.ratelimiters.enabled: false # 关闭限流器健康检查

info:
  name: ${spring.application.name}
  description: resilience4j demo
  environment: ${spring.profiles.active}
  version: 0.0.1

management.metrics.tags.application: ${spring.application.name} # 添加自定义标签
management.metrics.distribution.percentiles-histogram.http.server.requests: true # 开启http请求统计
management.metrics.distribution.percentiles-histogram.resilience4j.circuitbreaker.calls: true # 开启断路器统计

#resilience4j.circuitbreaker.metrics.use_legacy_binder: true # 使用旧版绑定器

resilience4j.circuitbreaker: # 断路器配置
  configs:
    default:
      registerHealthIndicator: true # 开启健康检查
      slidingWindowSize: 10 # 滑动窗口大小
      minimumNumberOfCalls: 5 # 最小调用次数
      permittedNumberOfCallsInHalfOpenState: 3 # 半开状态最大调用次数
      automaticTransitionFromOpenToHalfOpenEnabled: true # 自动切换到半开状态
      waitDurationInOpenState: 5s # 半开状态等待时间
      failureRateThreshold: 50 # 失败率阈值
      eventConsumerBufferSize: 10 # 事件消费者缓冲区大小
      recordExceptions: # 记录异常
        - org.springframework.web.client.HttpServerErrorException # http服务端错误
        - java.util.concurrent.TimeoutException # 超时异常
        - java.io.IOException # IO异常
      ignoreExceptions: # 忽略异常
        - io.github.robwin.exception.BusinessException # 业务异常
    shared: # 共享配置
      slidingWindowSize: 100 # 滑动窗口大小
      permittedNumberOfCallsInHalfOpenState: 30 # 半开状态最大调用次数
      waitDurationInOpenState: 1s # 半开状态等待时间
      failureRateThreshold: 50 # 失败率阈值
      eventConsumerBufferSize: 10 # 事件消费者缓冲区大小
      ignoreExceptions: # 忽略异常
        - io.github.robwin.exception.BusinessException # 业务异常
  instances: # 实例配置
    backendA: # 配置 backendA 实例
      baseConfig: default # 使用 default 配置
    backendB: # 配置 backendB 实例
      registerHealthIndicator: true # 开启健康检查
      slidingWindowSize: 10 # 滑动窗口大小
      minimumNumberOfCalls: 10 # 最小调用次数
      permittedNumberOfCallsInHalfOpenState: 3 # 半开状态最大调用次数
      waitDurationInOpenState: 5s # 半开状态等待时间
      failureRateThreshold: 50 # 失败率阈值
      eventConsumerBufferSize: 10 # 事件消费者缓冲区大小
      recordFailurePredicate: io.github.robwin.exception.RecordFailurePredicate # 记录异常
resilience4j.retry: # 重试配置
  configs:
    default:
      maxAttempts: 3 # 最大重试次数
      waitDuration: 100 # 重试间隔时间 (ms)
      retryExceptions: # 记录异常
        - org.springframework.web.client.HttpServerErrorException # http服务端错误
        - java.util.concurrent.TimeoutException # 超时异常
        - java.io.IOException # IO异常
      ignoreExceptions: # 忽略异常
        - io.github.robwin.exception.BusinessException # 业务异常
  instances:
    backendA: # 配置 backendA 实例
      baseConfig: default # 使用 default 配置
    backendB: # 配置 backendB 实例
      baseConfig: default # 使用 default 配置
resilience4j.bulkhead: # 舱壁 批量请求配置
  configs:
    default:
      maxConcurrentCalls: 100 # 最大并发调用数
  instances:
    backendA: # 配置 backendA 实例
      maxConcurrentCalls: 10 # 最大并发调用数
    backendB:
      maxWaitDuration: 10ms # 最大等待时间
      maxConcurrentCalls: 20 # 最大并发调用数

resilience4j.thread-pool-bulkhead: # 线程池舱壁 批量请求配置
  configs:
    default:
      maxThreadPoolSize: 4 # 最大线程池大小
      coreThreadPoolSize: 2 # 核心线程池大小
      queueCapacity: 2 # 队列容量
  instances:
    backendA:
      baseConfig: default # 使用 default 配置
    backendB:
      maxThreadPoolSize: 1 # 覆盖默认配置,最大线程池大小
      coreThreadPoolSize: 1 # 覆盖默认配置,核心线程池大小
      queueCapacity: 1 # 覆盖默认配置,队列容量

resilience4j.ratelimiter: # 限流器配置
  configs:
    default:
      registerHealthIndicator: false # 关闭健康检查
      limitForPeriod: 10 # 每个周期内的请求限制数
      limitRefreshPeriod: 1s # 周期刷新时间,即每秒刷新一次
      timeoutDuration: 0 # 请求超时时间,0表示不超时
      eventConsumerBufferSize: 100 # 事件消费者缓冲区大小
  instances:
    backendA:
      baseConfig: default # 使用默认配置
    backendB:
      limitForPeriod: 6 # 每个周期内的请求限制数
      limitRefreshPeriod: 500ms # 周期刷新时间,即每500毫秒刷新一次
      timeoutDuration: 3s # 请求超时时间,3秒

resilience4j.timelimiter: # 限时器配置
  configs:
    default:
      cancelRunningFuture: false # 是否取消正在运行的Future
      timeoutDuration: 2s # 超时时间,2秒
  instances:
    backendA:
      baseConfig: default # 使用默认配置
    backendB:
      baseConfig: default # 使用默认配置

 3.依赖

 <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>


    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <resilience4j.version>2.0.2</resilience4j.version>
    </properties>

    <dependencies>
        <!-- Spring Boot Starters -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

        <!-- Resilience4j -->
        <dependency>
            <groupId>io.github.resilience4j</groupId>
            <artifactId>resilience4j-spring-boot2</artifactId>
            <version>${resilience4j.version}</version>
        </dependency>
        <dependency>
            <groupId>io.github.resilience4j</groupId>
            <artifactId>resilience4j-all</artifactId>
            <version>${resilience4j.version}</version>
        </dependency>
        <dependency>
            <groupId>io.github.resilience4j</groupId>
            <artifactId>resilience4j-reactor</artifactId>
            <version>${resilience4j.version}</version>
        </dependency>

        <!-- Micrometer Prometheus -->
        <dependency>
            <groupId>io.micrometer</groupId>
            <artifactId>micrometer-registry-prometheus</artifactId>
        </dependency>

        <!-- Chaos Monkey for Spring Boot -->
        <dependency>
            <groupId>de.codecentric</groupId>
            <artifactId>chaos-monkey-spring-boot</artifactId>
            <version>2.7.0</version>
        </dependency>

        <!-- Vavr Jackson -->
        <dependency>
            <groupId>io.vavr</groupId>
            <artifactId>vavr-jackson</artifactId>
            <version>0.10.3</version>
        </dependency>

        <!-- Test Dependencies -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.projectreactor</groupId>
            <artifactId>reactor-test</artifactId>
            <version>3.4.22</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

 这里正好用Prometheus和Grafana看看效果

4 总结

通过本文的介绍,你应该已经了解了如何在 Spring Boot 项目中配置和使用 Resilience4j 来实现断路器、重试、舱壁、限流器和限时器等功能,Resilience4j 提供了丰富的配置选项和灵活的使用方式,帮助你构建弹性的微服务。

  • 10
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
你可以通过在Feign客户端上添加Resilience4j的拦截器来实现熔断逻辑。下面是一些步骤来实现这个过程: 1. 首先,确保你已经添加了Resilience4j的依赖到你的项目。你可以在Maven或者Gradle配置文件添加以下依赖: ```xml <dependency> <groupId>io.github.resilience4j</groupId> <artifactId>resilience4j-spring-cloud2</artifactId> <version>1.6.1</version> </dependency> ``` 2. 创建一个实现Feign的RequestInterceptor接口的类,用于拦截Feign的请求。以下是一个示例: ```java import feign.RequestInterceptor; import feign.RequestTemplate; import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class Resilience4jFeignInterceptor implements RequestInterceptor { private final CircuitBreakerRegistry circuitBreakerRegistry; @Autowired public Resilience4jFeignInterceptor(CircuitBreakerRegistry circuitBreakerRegistry) { this.circuitBreakerRegistry = circuitBreakerRegistry; } @Override public void apply(RequestTemplate requestTemplate) { String serviceName = requestTemplate.feignTarget().name(); circuitBreakerRegistry.circuitBreaker(serviceName).executeRunnable(() -> { // 在这里执行你的Feign请求 requestTemplate.header("Authorization", "Bearer your-token"); }); } } ``` 3. 在你的Feign客户端接口上添加`configuration`属性,使用上述的拦截器类。例如: ```java import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; @FeignClient(name = "your-service-name", configuration = Resilience4jFeignInterceptor.class) public interface YourFeignClient { @GetMapping("/your-endpoint") String yourFeignMethod(); } ``` 这样,当你使用`YourFeignClient`接口的方法发送请求时,请求将会通过Resilience4j的断路器进行拦截和熔断处理。 请注意,上面的示例使用了`CircuitBreakerRegistry`来获取相应的断路器实例。你需要根据你的实际需求进行配置和使用Resilience4j的断路器。另外,你还可以根据需要添加其他的Resilience4j功能,如限流、重试等。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值