Spring Boot集成Resilience4J實現(xiàn)限流/重試/隔離
1.前言
本篇文章主要講述基于Resilience4J實現(xiàn)限流/重試/隔離。
2.代碼工程
pom.xml
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot3</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>限流
@RequestMapping("/hello")
@RateLimiter(name="ratelimitApi",fallbackMethod = "fallback")
public ResponseEntity<String> showHelloWorld(){
return new ResponseEntity<>("success",HttpStatus.OK);
}
public ResponseEntity fallback(Throwable e){
log.error("fallback exception , {}",e.getMessage());
return new ResponseEntity<>("your request is too fast,please low down", HttpStatus.OK);
}重試
@RequestMapping("/retry")
@Retry(name = "backendA")//use backendA ,if throw IOException ,it will be retried 3 times。
public ResponseEntity<String> retry(String name){
if(name.equals("test")){
i++;
log.info("retry time:{}",i);
throw new HttpServerErrorException(HttpStatusCode.valueOf(101));
}
return new ResponseEntity<>("retry",HttpStatus.OK);
}隔離
@RequestMapping("/bulkhead")
@Bulkhead(name = "backendA")
public ResponseEntity<String> bulkhead(){
return new ResponseEntity<>("bulkhead",HttpStatus.OK);
}配置文件
spring:
application.name: resilience4j-demo
jackson.serialization.indent_output: true
management:
endpoints.web.exposure.include:
- '*'
endpoint.health.show-details: always
health.circuitbreakers.enabled: true
resilience4j:
circuitbreaker:
configs:
default:
registerHealthIndicator: true
slidingWindowSize: 10
minimumNumberOfCalls: 5
permittedNumberOfCallsInHalfOpenState: 3
automaticTransitionFromOpenToHalfOpenEnabled: true
waitDurationInOpenState: 5s
failureRateThreshold: 50
eventConsumerBufferSize: 10
ratelimiter:
instances:
ratelimitApi:
limit-for-period: 5
limit-refresh-period: 1s
timeout-duration: 100ms
retry:
instances:
backendA:
maxAttempts: 3
waitDuration: 10s
enableExponentialBackoff: true
exponentialBackoffMultiplier: 2
retryExceptions:
- org.springframework.web.client.HttpServerErrorException
- java.io.IOException
bulkhead:
instances:
backendA:
maxConcurrentCalls: 10以上只是一些關鍵代碼,所有代碼請參見下面代碼倉庫
代碼倉庫
GitHub - Harries/springboot-demo: a simple springboot demo with some components for example: redis,solr,rockmq and so on.(Resilience4J)
3.測試
1.啟動Spring Boot應用程序
測試限流
public class ThreadTest {
public static void main(String[] args) {
for(int i=0;i<6;i++){
new Thread(()->{
System.out.println(new RestTemplate().getForObject("http://localhost:8080/hello",String.class));
}).start();
}
}
}運行main方法
io.github.resilience4j.bulkhead.BulkheadFullException: Bulkhead 'backendA' is full and does not permit further calls at io.github.resilience4j.bulkhead.BulkheadFullException.createBulkheadFullException(BulkheadFullException.java:49) ~[resilience4j-bulkhead-2.0.2.jar:2.0.2] at io.github.resilience4j.bulkhead.internal.SemaphoreBulkhead.acquirePermission(SemaphoreBulkhead.java:164) ~[resilience4j-bulkhead-2.0.2.jar:2.0.2] at io.github.resilience4j.bulkhead.Bulkhead.lambda$decorateCheckedSupplier$0(Bulkhead.java:68) ~[resilience4j-bulkhead-2.0.2.jar:2.0.2] at io.github.resilience4j.bulkhead.Bulkhead.executeCheckedSupplier(Bulkhead.java:471) ~[resilience4j-bulkhead-2.0.2.jar:2.0.2] at io.github.resilience4j.spring6.bulkhead.configure.BulkheadAspect.handleJoinPoint(BulkheadAspect.java:194) ~[resilience4j-spring6-2.0.2.jar:2.0.2] at io.github.resilience4j.spring6.bulkhead.configure.BulkheadAspect.proceed(BulkheadAspect.java:147) ~[resilience4j-spring6-2.0.2.jar:2.0.2] at io.github.resilience4j.spring6.bulkhead.configure.BulkheadAspect.lambda$bulkheadAroundAdvice$1(BulkheadAspect.java:120) ~[resilience4j-spring6-2.0.2.jar:2.0.2] at io.github.resilience4j.spring6.fallback.FallbackExecutor.execute(FallbackExecutor.java:37) ~[resilience4j-spring6-2.0.2.jar:2.0.2] at io.github.resilience4j.spring6.bulkhead.configure.BulkheadAspect.bulkheadAroundAdvice(BulkheadAspect.java:121) ~[resilience4j-spring6-2.0.2.jar:2.0.2] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na] at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:637) ~[spring-aop-6.1.2.jar:6.1.2]
測試重試
訪問http://127.0.0.1:8080/retry?name=test
2024-08-03T23:16:32.092+08:00 INFO 5097 --- [resilience4j-demo] [nio-8080-exec-9] c.e.r.controller.HelloWorldController : retry time:1 2024-08-03T23:16:42.120+08:00 INFO 5097 --- [resilience4j-demo] [nio-8080-exec-9] c.e.r.controller.HelloWorldController : retry time:2 2024-08-03T23:17:02.142+08:00 INFO 5097 --- [resilience4j-demo] [nio-8080-exec-9] c.e.r.controller.HelloWorldController : retry time:3 2024-08-03T23:17:02.165+08:00 ERROR 5097 --- [resilience4j-demo] [nio-8080-exec-9] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.web.client.HttpServerErrorException: 101 SWITCHING_PROTOCOLS] with root cause org.springframework.web.client.HttpServerErrorException: 101 SWITCHING_PROTOCOLS at com.et.resilience4j.controller.HelloWorldController.retry(HelloWorldController.java:37) ~[classes/:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na] at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:352) ~[spring-aop-6.1.2.jar:6.1.2] at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196) ~[spring-aop-6.1.2.jar:6.1.2]
測試隔離
public class ThreadTest {
public static void main(String[] args) {
/* for(int i=0;i<6;i++){
new Thread(()->{
System.out.println(new RestTemplate().getForObject("http://localhost:8080/hello",String.class));
}).start();
}*/
for(int i=0;i<11;i++){
new Thread(()->{
System.out.println(new RestTemplate().getForObject("http://localhost:8080/bulkhead",String.class));
}).start();
}
}
}運行main方法
2024-08-03T23:17:36.943+08:00 ERROR 5097 --- [resilience4j-demo] [nio-8080-exec-5] c.e.r.controller.HelloWorldController : fallback exception , RateLimiter 'ratelimitApi' does not permit further calls
以上就是Spring Boot集成Resilience4J實現(xiàn)限流/重試/隔離的詳細內容,更多關于SpringBoot集成Resilience4j的資料請關注腳本之家其它相關文章!
相關文章
Java 中的vector和list的區(qū)別和使用實例詳解
在大家還沒有了解vector,list,deque的知識之前,我先給大家介紹下stl,本文重點給大家介紹vector和list的區(qū)別及使用,感興趣的的朋友一起看看吧2017-09-09
java.io.IOException:你的主機中的軟件中止了一個已建立的連接踩坑實戰(zhàn)
最近在工作中遇到了個問題,分享給同樣遇到問題的同學,這篇文章主要給大家介紹了關于java.io.IOException:你的主機中的軟件中止了一個已建立的連接的踩坑實戰(zhàn)記錄,需要的朋友可以參考下2023-03-03
java實現(xiàn)列表、集合與數(shù)組之間轉化的方法
這篇文章主要介紹了java實現(xiàn)列表、集合與數(shù)組之間轉化的方法,涉及java中列表、集合與數(shù)組相互轉換的技巧,非常具有實用價值,需要的朋友可以參考下2015-03-03
MybatisPlus3.3.1整合clickhouse的過程
這篇文章主要介紹了MybatisPlus3.3.1整合clickhouse的過程,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧2025-05-05

