Spring Boot集成Resilience4J實(shí)現(xiàn)限流/重試/隔離
1.前言
本篇文章主要講述基于Resilience4J實(shí)現(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
以上只是一些關(guān)鍵代碼,所有代碼請(qǐng)參見(jiàn)下面代碼倉(cāng)庫(kù)
代碼倉(cāng)庫(kù)
GitHub - Harries/springboot-demo: a simple springboot demo with some components for example: redis,solr,rockmq and so on.(Resilience4J)
3.測(cè)試
1.啟動(dòng)Spring Boot應(yīng)用程序
測(cè)試限流
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(); } } }
運(yùn)行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]
測(cè)試重試
訪問(wèn)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]
測(cè)試隔離
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(); } } }
運(yùn)行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實(shí)現(xiàn)限流/重試/隔離的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot集成Resilience4j的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java實(shí)現(xiàn)自定義LinkedList類(lèi)的示例代碼
LinkedList類(lèi)跟ArrayList類(lèi)不同,它通過(guò)指針以及結(jié)點(diǎn)的操作對(duì)鏈表進(jìn)行增刪改查。本文就來(lái)和大家分享下Java如何為實(shí)現(xiàn)自定義LinkedList類(lèi),需要的可以參考一下2022-08-08SpringBoot接口限流的實(shí)現(xiàn)方法小結(jié)
在一個(gè)高并發(fā)系統(tǒng)中對(duì)流量的把控是非常重要的,當(dāng)巨大的流量直接請(qǐng)求到我們的服務(wù)器上沒(méi)多久就可能造成接口不可用,不處理的話甚至?xí)斐烧麄€(gè)應(yīng)用不可用,所以我們需要接口限流,本文給大家介紹了SpringBoot接口限流的實(shí)現(xiàn)方法,需要的朋友可以參考下2024-10-10Java中string和int的互相轉(zhuǎn)換問(wèn)題
本文通過(guò)實(shí)例代碼給大家詳細(xì)介紹了Java中string和int的互相轉(zhuǎn)換問(wèn)題,感興趣的朋友一起看看吧2017-10-10SpringBoot之Java配置的實(shí)現(xiàn)
這篇文章主要介紹了SpringBoot之Java配置的實(shí)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-01-01Java 實(shí)現(xiàn)鏈表結(jié)點(diǎn)插入
這篇文章主要介紹了Java 實(shí)現(xiàn)鏈表結(jié)點(diǎn)插入操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-02-02java微信開(kāi)發(fā)API第三步 微信獲取以及保存接口調(diào)用憑證
這篇文章主要為大家詳細(xì)介紹了java微信開(kāi)發(fā)API第二步,微信獲取以及保存接口調(diào)用憑證,感興趣的小伙伴們可以參考一下2016-06-06