济宁网站建设哪家好,dede网站建设教程云盘,手机上可视化编程app,新浪邮箱登录网页介绍
Resilience4j 是一个专为函数式编程而设计的轻量级容错库。Resilience4j 提供高阶函数#xff08;装饰器#xff09;#xff0c;以增强任何功能接口、lambda 表达式或方法引用#xff0c;包括断路器、速率限制器、重试或隔板。您可以在任何函数接口、lambda 表达式或…介绍
Resilience4j 是一个专为函数式编程而设计的轻量级容错库。Resilience4j 提供高阶函数装饰器以增强任何功能接口、lambda 表达式或方法引用包括断路器、速率限制器、重试或隔板。您可以在任何函数接口、lambda 表达式或方法引用上堆叠多个装饰器。优点是您可以选择所需的装饰器而没有别的。注意Resilience4j 2 需要 Java 17。
Resilience4j 提供高阶函数装饰器以增强任何功能接口、lambda 表达式或方法引用包括断路器、速率限制器、重试或隔板。您可以在任何函数接口、lambda 表达式或方法引用上堆叠多个装饰器。优点是您可以选择所需的装饰器而没有别的。
使用 Resilience4j可不全部使用可以选择您需要的东西。
示例
以下示例演示如何使用 CircuitBreaker 和 Retry 修饰 lambda 表达式以便在发生异常时重试调用 3 次。
您可以配置重试之间的等待间隔也可以配置自定义回退算法。
该示例使用 Vavr 的 Try monad 从异常中恢复并在所有重试都失败时调用另一个 lambda 表达式作为回退。
// 创建一个默认配置的CircuitBreaker
CircuitBreaker circuitBreaker CircuitBreaker.ofDefaults(backendService);// 创建一个默认配置的Retry
// 3次重试每次间隔500ms
Retry retry Retry.ofDefaults(backendService);// Create a Bulkhead with default configuration
Bulkhead bulkhead Bulkhead.ofDefaults(backendService);SupplierString supplier () - backendService.doSomething(param1, param2)// Decorate your call to backendService.doSomething()
// with a Bulkhead, CircuitBreaker and Retry
// **note: you will need the resilience4j-all dependency for this
SupplierString decoratedSupplier Decorators.ofSupplier(supplier).withCircuitBreaker(circuitBreaker).withBulkhead(bulkhead).withRetry(retry) .decorate();// When you dont want to decorate your lambda expression,
// but just execute it and protect the call by a CircuitBreaker.
String result circuitBreaker.executeSupplier(backendService::doSomething);// You can also run the supplier asynchronously in a ThreadPoolBulkheadThreadPoolBulkhead threadPoolBulkhead ThreadPoolBulkhead.ofDefaults(backendService);// The Scheduler is needed to schedule a timeout
// on a non-blocking CompletableFuture
ScheduledExecutorService scheduledExecutorService Executors.newScheduledThreadPool(3);
TimeLimiter timeLimiter TimeLimiter.of(Duration.ofSeconds(1));CompletableFutureString future Decorators.ofSupplier(supplier).withThreadPoolBulkhead(threadPoolBulkhead).withTimeLimiter(timeLimiter, scheduledExecutorService).withCircuitBreaker(circuitBreaker).withFallback(asList(TimeoutException.class, CallNotPermittedException.class, BulkheadFullException.class), throwable - Hello from Recovery).get().toCompletableFuture(); 所有核心模块和 Decorators 类
resilience4j-all 弹性4J-全部
Core modules 核心模块
resilience4j-circuitbreaker熔断resilience4j-ratelimiter速率限制resilience4j-bulkhead 舱壁resilience4j-retry自动重试同步和异步resilience4j-cache结果缓存resilience4j-timelimiter超时处理 Add-on modules 附加模块 resilience4j-feign假装适配器resilience4j-consumer循环缓冲区事件消费者resilience4j-kotlinKotlin 协程支持resilience4j-vavrVavr 支持 Frameworks modules 框架模块 resilience4j-spring-boot3: Spring Boot 3 Starterresilience4j-spring-boot2: Spring Boot 2 Starterresilience4j-micronaut: Micronaut Starter Reactive modules 电抗模块 resilience4j-rxjava2自定义 RxJava2 运算符resilience4j-rxjava3自定义 RxJava3 运算符resilience4j-reactor定制弹簧反应器操作器 Metrics modules 指标模块 resilience4j-micrometer 微米度量导出器resilience4j-metricsDropwizard 指标导出器
与 Netflix Hystrix 的比较
在 Hystrix 中对外部系统的调用必须包装在 HystrixCommand 中。相比之下resilience4j提供高阶函数装饰器以增强任何功能接口、lambda 表达式或带有断路器、限速器或隔板的方法引用。此外resilience4j还提供装饰器来重试失败的调用或缓存调用结果。您可以在任何函数接口、lambda 表达式或方法引用上堆叠多个装饰器。这意味着您可以将 Bulkhead、RateLimiter 和 Retry 装饰器与 CircuitBreaker 装饰器组合在一起。优点是您可以选择所需的装饰器而没有其他选择。任何修饰的函数都可以使用 CompletableFuture 或 RxJava 同步或异步执行。Hystrix 仅在半开状态下执行一次执行以确定是否关闭 CircuitBreaker。resilience4j允许执行可配置的执行次数并将结果与可配置的阈值进行比较以确定是否关闭断路器。resilience4j提供自定义 Reactor 或 RxJava 运算符以使用断路器、隔板或速率限制器装饰任何反应类型。Hystrix 和此库发出事件流这些事件流对系统操作员监控有关执行结果和延迟的指标很有用。
核心模块
CircuitBreaker 断路器
介绍
断路器通过有限状态机实现该状态机具有三种正常状态CLOSED、OPEN 和 HALF_OPEN 以及两种特殊状态 DISABLED 和 FORCED_OPEN。 CircuitBreaker 使用滑动窗口来存储和聚合调用结果。您可以在基于计数的滑动窗口和基于时间的滑动窗口之间进行选择。基于计数的滑动窗口聚合了最后 N 次调用的结果。基于时间的滑动窗口聚合了最后 N 秒的调用结果。
基于计数的滑动窗口
基于计数的滑动窗口是通过 N 个测量值的圆形阵列实现的。 如果计数窗口大小为 10则圆形数组始终具有 10 个测量值。 滑动窗口以增量方式更新总聚合。记录新的呼叫结果时总聚合将更新。当驱逐最早的测量值时将从总聚合中减去该测量值并重置存储桶。逐出时减法
检索 Snapshot 的时间是常量 O1因为 Snapshot 是预先聚合的并且与窗口大小无关。 此实现的空间要求内存消耗应为 On。
基于时间的滑动窗口
基于时间的滑动窗口是通过 N 个部分聚合桶的循环数组实现的。 如果时间窗口大小为 10 秒则圆形数组始终具有 10 个部分聚合存储桶。每个存储桶聚合在特定纪元秒内发生的所有调用的结果。部分聚合。圆形数组的 head 桶存储当前 epoch 秒的调用结果。其他部分聚合存储前几秒的调用结果。 滑动窗口不会单独存储调用结果元组而是以增量方式更新部分聚合存储桶和总聚合。 当记录新的呼叫结果时总聚合将以增量方式更新。当最旧的存储桶被逐出时将从总聚合中减去该存储桶的部分总聚合并重置该存储桶。逐出时减法
检索 Snapshot 的时间是常数 O1因为 Snapshot 是预先聚合的并且与时间窗口大小无关。 此实现的空间要求内存消耗应几乎为常量 On因为调用结果元组不是单独存储的。仅创建 N 个部分聚合和 1 个总聚合。
部分聚合由 3 个整数组成用于计算失败呼叫数、慢速呼叫数和呼叫总数。一个长用于存储所有调用的总持续时间。
故障率和慢速请求率阈值
情况一当故障率等于或大于可配置阈值时断路器的状态将从 CLOSED 更改为 OPEN。例如当超过 50% 的请求失败时。默认情况下所有异常都算作失败。可以定义应计为失败的异常列表。然后所有其他异常都算作成功除非它们被忽略。也可以忽略异常这样它们既不算作失败也不算成功。
情况二当慢速调用的百分比等于或大于可配置的阈值时断路器也会从 CLOSED 更改为 OPEN。例如当超过 50% 的请求时间超过 5 秒时。这有助于在外部系统实际无响应之前减少外部系统的负载。
只有在记录了最小呼叫数的情况下才能计算故障率和慢速呼叫率。例如如果所需的最小呼叫数为 10则必须至少记录 10 个呼叫然后才能计算故障率。如果仅评估了 9 个呼叫即使所有 9 个呼叫都失败断路器也不会跳闸打开。
CircuitBreaker 在 OPEN 时拒绝带有 的 CallNotPermittedException 请求。等待时间过后断路器状态将从 OPEN 更改为 HALF_OPEN并允许可配置的调用次数以查看后端是否仍然不可用或已再次可用。进一步的请求将被拒绝 CallNotPermittedException 直到 所有允许的呼叫都完成。 如果故障率或慢速调用率等于或大于配置的阈值则状态将变回 OPEN。如果故障率和慢速调用率低于阈值则状态将变回 CLOSED。
断路器支持另外两种特殊状态即 DISABLED始终允许访问和 FORCED_OPEN始终拒绝访问。在这两种状态下不会生成断路器事件状态转换除外也不会记录任何指标。退出这些状态的唯一方法是触发状态转换或重置断路器。
CircuitBreaker 是线程安全的如下所示
CircuitBreaker 的状态存储在 AtomicReference 中CircuitBreaker 使用原子操作通过无副作用功能更新状态。从滑动窗口录制通话和读取快照是同步的
这意味着应该保证原子性并且只有一个线程能够在某个时间点更新状态或滑动窗口。
但 CircuitBreaker 不会同步函数调用。这意味着函数调用本身不是关键部分的一部分。否则断路器将引入巨大的性能损失和瓶颈。缓慢的函数调用将对整体性能/吞吐量产生巨大的负面影响。
如果 20 个并发线程请求执行函数的权限并且 CircuitBreaker 的状态为关闭则允许所有线程调用该函数。即使滑动窗口大小为 15。滑动窗口并不意味着只允许同时运行 15 个调用。如果要限制并发线程数请使用 Bulkhead。可以组合使用隔板和断路器。
创建 CircuitBreakerRegistry
Resilience4j 带有一个基于 ConcurrentHashMap 的内存 CircuitBreakerRegistry 它提供线程安全性和原子性保证。您可以使用 CircuitBreakerRegistry 管理创建和检索CircuitBreaker 实例。您可以为所有 CircuitBreaker 实例创建具有全局默认值 CircuitBreakerConfig 的 CircuitBreakerRegistry如下所示。
CircuitBreakerRegistry circuitBreakerRegistry CircuitBreakerRegistry.ofDefaults();
创建和配置断路器
您可以提供自己的自定义全局 CircuitBreakerConfig .要创建自定义全局 CircuitBreakerConfig可以使用 CircuitBreakerConfig 构建器。您可以使用构建器配置以下属性。
Config property Config Default Value DescriptionfailureRateThreshold50以百分比为单位配置故障率阈值。 当故障率等于或大于阈值时断路器将转换为打开并开始短路呼叫。slowCallRateThreshold100以百分比为单位配置阈值。当呼叫持续时间大于 slowCallDurationThreshold 当慢速呼叫的百分比等于或大于阈值时断路器将转换为打开并开始短路呼叫。slowCallDurationThreshold60000 [ms]Configures the duration threshold above which calls are considered as slow and increase the rate of slow calls. 配置持续时间阈值超过该阈值的呼叫将被视为慢速呼叫并提高慢速呼叫的速率。permittedNumberOfCalls InHalfOpenState 10配置断路器半开时允许的呼叫次数。maxWaitDurationInHalfOpenState0 [ms] 配置最大等待持续时间该持续时间控制断路器在切换为打开之前可以保持半开状态的最长时间。 值 0 表示断路器将在半开状态下无限等待直到完成所有允许的调用。slidingWindowTypeCOUNT_BASED配置滑动窗口的类型该滑动窗口用于在断路器关闭时记录呼叫结果。 滑动窗口可以是基于计数的也可以是基于时间的。 如果滑动窗口为COUNT_BASED则记录并汇总最后的 slidingWindowSize 呼叫。 如果滑动窗口TIME_BASED则记录并汇总最后 slidingWindowSize 几秒的呼叫。slidingWindowSize100配置滑动窗口的大小该滑动窗口用于记录断路器关闭时的呼叫结果。minimumNumberOfCalls100配置断路器计算错误率或慢速呼叫率之前所需的最小呼叫数每个滑动窗口周期。 例如如果 minimumNumberOfCalls 为 10则必须至少记录 10 个调用然后才能计算失败率。 如果只记录了 9 个请求即使所有 9 个请求都失败断路器也不会转换为打开。waitDurationInOpenState60000 [ms] 断路器在从打开状态转换到半打开状态之前应等待的时间。automaticTransition FromOpenToHalfOpenEnabled false如果设置为 true则表示 CircuitBreaker 将自动从打开状态转换为半打开状态无需调用即可触发转换。创建一个线程来监视 CircuitBreakers 的所有实例以便在 waitDurationInOpenState 通过后将它们转换为HALF_OPEN。然而如果设置为 false则仅在进行调用时才会转换为 HALF_OPEN即使在传递 waitDurationInOpenState 之后也是如此。这样做的好处是没有线程监控所有断路器的状态。recordExceptionsempty记录为失败并因此增加失败率的异常列表。 任何匹配或从其中一个列表继承的异常都算作失败除非通过 ignoreExceptions 显式忽略 . 如果指定异常列表则所有其他异常都算作成功除非 ignoreExceptions 显式忽略它们。ignoreExceptionsempty被忽略且既不算作失败也不算成功的异常列表。 任何匹配或从其中一个列表继承的异常都不会算作失败或成功即使异常是 recordExceptions 的一部分。recordFailurePredicatethrowable - true 默认情况下所有异常都作为失败进行重构。一个自定义谓词用于评估是否应将异常记录为失败。 如果异常应计为失败则谓词必须返回 true。如果异常则谓词必须返回 false 应算作成功除非 ignoreExceptions 显式忽略异常。ignoreExceptionPredicatethrowable - false 默认情况下不会忽略任何异常。一个自定义谓词用于评估是否应忽略异常并且既不算作失败也不算成功。 如果应忽略异常则 Predicate 必须返回 true。 如果异常应计为失败则谓词必须返回 false。
// Create a custom configuration for a CircuitBreaker
CircuitBreakerConfig circuitBreakerConfig CircuitBreakerConfig.custom().failureRateThreshold(50).slowCallRateThreshold(50).waitDurationInOpenState(Duration.ofMillis(1000)).slowCallDurationThreshold(Duration.ofSeconds(2)).permittedNumberOfCallsInHalfOpenState(3).minimumNumberOfCalls(10).slidingWindowType(SlidingWindowType.TIME_BASED).slidingWindowSize(5).recordException(e - INTERNAL_SERVER_ERROR.equals(getResponse().getStatus())).recordExceptions(IOException.class, TimeoutException.class).ignoreExceptions(BusinessException.class, OtherBusinessException.class).build();// Create a CircuitBreakerRegistry with a custom global configuration
CircuitBreakerRegistry circuitBreakerRegistry CircuitBreakerRegistry.of(circuitBreakerConfig);// Get or create a CircuitBreaker from the CircuitBreakerRegistry
// with the global default configuration
CircuitBreaker circuitBreakerWithDefaultConfig circuitBreakerRegistry.circuitBreaker(name1);// Get or create a CircuitBreaker from the CircuitBreakerRegistry
// with a custom configuration
CircuitBreaker circuitBreakerWithCustomConfig circuitBreakerRegistry.circuitBreaker(name2, circuitBreakerConfig);
您可以添加可由多个 CircuitBreaker 实例共享的配置。
CircuitBreakerConfig circuitBreakerConfig CircuitBreakerConfig.custom().failureRateThreshold(70).build();circuitBreakerRegistry.addConfiguration(someSharedConfig, config);CircuitBreaker circuitBreaker circuitBreakerRegistry.circuitBreaker(name, someSharedConfig);
您可以覆盖配置。
CircuitBreakerConfig defaultConfig circuitBreakerRegistry.getDefaultConfig();CircuitBreakerConfig overwrittenConfig CircuitBreakerConfig.from(defaultConfig).waitDurationInOpenState(Duration.ofSeconds(20)).build();
如果您不想使用 CircuitBreakerRegistry 管理 CircuitBreaker 实例也可以直接创建实例。
// Create a custom configuration for a CircuitBreaker
CircuitBreakerConfig circuitBreakerConfig CircuitBreakerConfig.custom().recordExceptions(IOException.class, TimeoutException.class).ignoreExceptions(BusinessException.class, OtherBusinessException.class).build();CircuitBreaker customCircuitBreaker CircuitBreaker.of(testName, circuitBreakerConfig);
CircuitBreaker 使用案例
pom文件
dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-circuitbreaker-resilience4j/artifactId
/dependency
!-- 由于断路保护等需要AOP实现所以必须导入AOP包 --
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-aop/artifactId
/dependency
yml文件配置
spring:cloud:circuitbreaker:enabled: truegroup:enabled: true #没开分组永远不用分组的配置。精确优先、分组次之(开了分组)、默认最后# Resilience4j CircuitBreaker 按照次数COUNT_BASED 的例子
# 6次访问中当执行方法的失败率达到50%时CircuitBreaker将进入开启OPEN状态(保险丝跳闸断电)拒绝所有请求。
# 等待5秒后CircuitBreaker 将自动从开启OPEN状态过渡到半开HALF_OPEN状态允许一些请求通过以测试服务是否恢复正常。
# 如还是异常CircuitBreaker 将重新进入开启OPEN状态如正常将进入关闭CLOSE闭合状态恢复正常处理请求。
# Resilience4j CircuitBreaker 按照时间TIME_BASED 的例子
resilience4j:timelimiter:configs:default:timeout-duration: 10s #神坑的位置timelimiter 默认限制远程1s超于1s就超时异常配置了降级就走降级逻辑circuitbreaker:configs:default:failureRateThreshold: 50 #设置50%的调用失败时打开断路器超过失败请求百分⽐CircuitBreaker变为OPEN状态。slowCallDurationThreshold: 2s #慢调用时间阈值高于这个阈值的视为慢调用并增加慢调用比例。slowCallRateThreshold: 30 #慢调用百分比峰值断路器把调用时间⼤于slowCallDurationThreshold视为慢调用当慢调用比例高于阈值断路器打开并开启服务降级slidingWindowType: TIME_BASED # 滑动窗口的类型slidingWindowSize: 2 #滑动窗口的大小配置配置TIME_BASED表示2秒minimumNumberOfCalls: 2 #断路器计算失败率或慢调用率之前所需的最小样本(每个滑动窗口周期)。permittedNumberOfCallsInHalfOpenState: 2 #半开状态允许的最大请求数默认值为10。waitDurationInOpenState: 5s #从OPEN到HALF_OPEN状态需要等待的时间recordExceptions:- java.lang.Exceptioninstances:cloud-payment-service:baseConfig: defaultController层 package com.atguigu.cloud.controller;import com.atguigu.cloud.apis.PayFeignApi;
import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;/*** auther zzyy* create 2023-11-13 14:54* Resilience4j CircuitBreaker 的例子*/
RestController
public class OrderCircuitController
{Resourceprivate PayFeignApi payFeignApi;GetMapping(value /feign/pay/circuit/{id})CircuitBreaker(name cloud-payment-service, fallbackMethod myCircuitFallback)public String myCircuitBreaker(PathVariable(id) Integer id){return payFeignApi.myCircuit(id);}//myCircuitFallback就是服务降级后的兜底处理方法public String myCircuitFallback(Integer id,Throwable t) {// 这里是容错处理逻辑返回备用结果return myCircuitFallback系统繁忙请稍后再试-----/(ㄒoㄒ)/~~;}
}
Bulkhead隔离
介绍
Resilience4j 提供了两种隔离模式的实现可用于限制并发执行的数量
a SemaphoreBulkhead 使用信号量a FixedThreadPoolBulkhead 使用有界队列和固定线程池。
它应该 SemaphoreBulkhead 在各种线程和 I/O 模型中都能很好地工作。它基于信号量与 Hystrix 不同它不提供“影子”线程池选项。客户端需要确保正确的线程池大小该大小将与隔板配置一致。
创建 BulkheadRegistry
就像 CircuitBreaker 模块一样此模块提供了一个内存 BulkheadRegistry 中和一个 ThreadPoolBulkheadRegistry 可用于管理创建和检索Bulkhead 实例的内存。
BulkheadRegistry bulkheadRegistry BulkheadRegistry.ofDefaults();ThreadPoolBulkheadRegistry threadPoolBulkheadRegistry ThreadPoolBulkheadRegistry.ofDefaults();
创建和配置隔板
Config property Default value DescriptionmaxConcurrentCalls25隔离允许的最大并行执行量maxWaitDuration0尝试进入饱和隔板时应阻塞并发的最大时间。
// Create a custom configuration for a Bulkhead
BulkheadConfig config BulkheadConfig.custom().maxConcurrentCalls(150).maxWaitDuration(Duration.ofMillis(500)).build();// Create a BulkheadRegistry with a custom global configuration
BulkheadRegistry registry BulkheadRegistry.of(config);// Get or create a Bulkhead from the registry -
// bulkhead will be backed by the default config
Bulkhead bulkheadWithDefaultConfig registry.bulkhead(name1);// Get or create a Bulkhead from the registry,
// use a custom configuration when creating the bulkhead
Bulkhead bulkheadWithCustomConfig registry.bulkhead(name2, custom);
创建和配置 ThreadPoolBulkhead
可以提供自定义全局 ThreadPoolBulkheadConfig。若要创建自定义全局 ThreadPoolBulkheadConfig可以使用 ThreadPoolBulkheadConfig 生成器。您可以使用构建器配置以下属性。
Config property Default value DescriptionmaxThreadPoolSizeRuntime.getRuntime() .availableProcessors() 配置最大线程池大小。coreThreadPoolSizeRuntime.getRuntime() .availableProcessors - 1配置核心线程池大小queueCapacity100配置队列的容量。keepAliveDuration20 [ms] 当线程数大于核心数时这是多余的空闲线程在终止之前等待新任务的最长时间。writableStackTraceEnabledtrue引发隔板异常时输出堆栈跟踪错误。 如果为 false则输出带有隔板异常的单行。
ThreadPoolBulkheadConfig config ThreadPoolBulkheadConfig.custom().maxThreadPoolSize(10).coreThreadPoolSize(2).queueCapacity(20).build();// Create a BulkheadRegistry with a custom global configuration
ThreadPoolBulkheadRegistry registry ThreadPoolBulkheadRegistry.of(config);// Get or create a ThreadPoolBulkhead from the registry -
// bulkhead will be backed by the default config
ThreadPoolBulkhead bulkheadWithDefaultConfig registry.bulkhead(name1);// Get or create a Bulkhead from the registry,
// use a custom configuration when creating the bulkhead
ThreadPoolBulkheadConfig custom ThreadPoolBulkheadConfig.custom().maxThreadPoolSize(5).build();ThreadPoolBulkhead bulkheadWithCustomConfig registry.bulkhead(name2, custom);
Bulihead使用案例
pom文件
!--resilience4j-bulkhead--
dependencygroupIdio.github.resilience4j/groupIdartifactIdresilience4j-bulkhead/artifactId
/dependency
yml配置
####resilience4j bulkhead 的例子
resilience4j:bulkhead:configs:default:maxConcurrentCalls: 2 # 隔离允许并发线程执行的最大数量maxWaitDuration: 1s # 当达到并发调用数量时新的线程的阻塞时间我只愿意等待1秒过时不候进舱壁兜底fallbackinstances:cloud-payment-service:baseConfig: defaulttimelimiter:configs:default:timeout-duration: 20s
Controller层
GetMapping(value /feign/pay/bulkhead/{id})
Bulkhead(name cloud-payment-service,fallbackMethod myBulkheadFallback,type Bulkhead.Type.SEMAPHORE)
public String myBulkhead(PathVariable(id) Integer id)
{return payFeignApi.myBulkhead(id);
}
public String myBulkheadFallback(Throwable t)
{return myBulkheadFallback隔板超出最大数量限制系统繁忙请稍后再试-----/(ㄒoㄒ)/~~;
}
RateLimiter限流
限流是准备 API 以进行扩展并建立服务的高可用性和可靠性的必要技术。而且这种技术还带有一大堆不同的选项用于如何处理检测到的限制盈余或者您要限制哪种类型的请求。您可以简单地拒绝此超限请求或者构建一个队列以稍后执行它们或者以某种方式组合这两种方法。
内部
Resilience4j 提供了一个 RateLimiter它将从纪元开始的所有纳秒拆分为多个周期。每个周期的持续时间由 配置。 RateLimiterConfig.limitRefreshPeriod 在每个周期开始时RateLimiter 将活动权限数设置为 RateLimiterConfig.limitForPeriod 。
对于 RateLimiter 调用者来说它看起来确实是这样的但对于 AtomicRateLimiter 实现来说如果未主动使用 RateLimiter则在后台进行了一些优化这些优化将跳过此刷新。 限流使用
pom文件
!--resilience4j-ratelimiter--
dependencygroupIdio.github.resilience4j/groupIdartifactIdresilience4j-ratelimiter/artifactId
/dependency
yml配置
####resilience4j ratelimiter 限流的例子
resilience4j:ratelimiter:configs:default:limitForPeriod: 2 #在一次刷新周期内允许执行的最大请求数limitRefreshPeriod: 1s # 限流器每隔limitRefreshPeriod刷新一次将允许处理的最大请求数量重置为limitForPeriodtimeout-duration: 1 # 线程等待权限的默认等待时间instances:cloud-payment-service:baseConfig: default
controller层
GetMapping(value /feign/pay/ratelimit/{id})
RateLimiter(name cloud-payment-service,fallbackMethod myRatelimitFallback)
public String myBulkhead(PathVariable(id) Integer id)
{return payFeignApi.myRatelimit(id);
}
public String myRatelimitFallback(Integer id,Throwable t)
{return 你被限流了禁止访问/(ㄒoㄒ)/~~;
}