Spring Boot集成Resilience4J实现限流/重试/隔离
1.前言
上篇文章讲了Resilience4J实现熔断功能,文章详见:Spring Boot集成Resilience4J实现断路器功能 | Harries Blog™,本篇文章主要讲述基于Resilience4J实现限流/重试/隔离。
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-demojackson.serialization.indent_output: truemanagement:endpoints.web.exposure.include:- '*'endpoint.health.show-details: alwayshealth.circuitbreakers.enabled: trueresilience4j:circuitbreaker:configs:default:registerHealthIndicator: trueslidingWindowSize: 10minimumNumberOfCalls: 5permittedNumberOfCallsInHalfOpenState: 3automaticTransitionFromOpenToHalfOpenEnabled: truewaitDurationInOpenState: 5sfailureRateThreshold: 50eventConsumerBufferSize: 10ratelimiter: instances:ratelimitApi:limit-for-period: 5 limit-refresh-period: 1s timeout-duration: 100ms retry:instances:backendA:maxAttempts: 3waitDuration: 10senableExponentialBackoff: trueexponentialBackoffMultiplier: 2retryExceptions:- org.springframework.web.client.HttpServerErrorException- java.io.IOExceptionbulkhead: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 callsat 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 causeorg.springframework.web.client.HttpServerErrorException: 101 SWITCHING_PROTOCOLSat 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实现限流/重试/隔离
1.前言 上篇文章讲了Resilience4J实现熔断功能,文章详见:Spring Boot集成Resilience4J实现断路器功能 | Harries Blog™,本篇文章主要讲述基于Resilience4J实现限流/重试/隔离。 2.代码工程 pom.xml <dependency><groupId>io…...
谷粒商城实战笔记-119~121-全文检索-ElasticSearch-mapping
文章目录 一,119-全文检索-ElasticSearch-映射-mapping创建1,Elasticsearch7开始不支持类型type。2,mapping2.1 Elasticsearch的Mapping 二,120-全文检索-ElasticSearch-映射-添加新的字段映射三,121-全文检索-Elastic…...
Java 并发编程:Java 线程池的介绍与使用
大家好,我是栗筝i,这篇文章是我的 “栗筝i 的 Java 技术栈” 专栏的第 024 篇文章,在 “栗筝i 的 Java 技术栈” 这个专栏中我会持续为大家更新 Java 技术相关全套技术栈内容。专栏的主要目标是已经有一定 Java 开发经验,并希望进…...
ubuntu上安装HBase伪分布式-2024年08月04日
ubuntu上安装HBase伪分布式-2024年08月04日 1.HBase介绍2.HBase与Hadoop的关系3.安装前言4.下载及安装5.单机配置6.伪分布式配置 1.HBase介绍 HBase是一个开源的非关系型数据库,它基于Google的Bigtable设计,用于支持对大型数据集的实时读写访问。HBase有…...
Mojo的特征与参数(参数化部分)详解
许多语言都具有元编程功能:即编写生成或修改代码的代码。Python 具有动态元编程功能:装饰器、元类等功能。这些功能使 Python 非常灵活且高效,但由于它们是动态的,因此会产生运行时开销。其他语言具有静态或编译时元编程功能,如 C 预处理器宏和 C++ 模板。这些功能可能受到…...
C++数组、vector求最大值最小值及其下标
使用 <algorithm> 头文件来查找数组或向量中最大值、最小值及其索引 #include <iostream> #include <vector> #include <algorithm> // 包含 std::max_element 和 std::min_elementint main() {std::vector<int> vec {3, 1, 4, 2, 5};// 查找最…...
内网安全:多种横向移动方式
1.MMC20.Application远程执行命令 2.ShellWindows远程执行命令 3.ShellBrowserWindow远程执行命令 4.WinRM远程执行命令横向移动 5.使用系统漏洞ms17010横向移动 DCOM: DCOM(分布式组件对象模型)是微软的一系列概念和程序接口。它支持不同…...
搭建 STM32 网关服务器的全流程:集成嵌入式 C++、TCP/IP 通信、Flash 存储及 JWT 认证(含代码示例)
引言 随着物联网(IoT)技术的快速发展,基于 STM32 的服务器(类似网关)在数据采集、设备控制等方面的应用越来越广泛。本文将介绍搭建一个基于 STM32 的服务器所需的技术栈,以及详细的搭建步骤和代码示例。 …...
一款免费强大的电脑锁屏工具,中文绿色免安装
这款软件主要特点是锁屏后不显示密码输入框,直接输入密码即可解锁。 ScreenBlur是一款功能强大的电脑屏幕锁软件,主要用于保护用户的隐私和数据安全。该软件的主要功能包括自动锁屏、隐藏桌面、加密锁机等。 功能特点 自动锁屏:用户可以设…...
Python | Leetcode Python题解之第319题灯泡开关
题目: 题解: class Solution:def bulbSwitch(self, n: int) -> int:return int(sqrt(n 0.5))...
前端Web-JavaScript(上)
要想让网页具备一定的交互效果,具有一定的动作行为,还得通过JavaScript来实现, 这门语言会让我们的页面能够和用户进行交互。 什么是JavaScript JavaScript(简称:JS) 是一门跨平台、面向对象的脚本语言,是…...
【积累】Python的类
类和方法的概念及实例 类 (Class):类是对具有相同属性和方法的对象集合的抽象描述。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。 方法:类中定义的函数。 构造方法 __init__():这是一个特殊的方法,会在类实例…...
Golang | Leetcode Golang题解之第318题最大单词长度乘积
题目: 题解: func maxProduct(words []string) (ans int) {masks : map[int]int{}for _, word : range words {mask : 0for _, ch : range word {mask | 1 << (ch - a)}if len(word) > masks[mask] {masks[mask] len(word)}}for x, lenX : ra…...
【感想】支持八股文在面试的应用
八股文:程序员面试中的利与弊 在现代社会的职场竞争中,尤其是IT行业,面试环节常常成为决定一个人能否入职的重要关卡。在这其中,“八股文”作为一种被广泛应用的考核工具,已经成为面试中不可或缺的一部分。然而&#…...
B - 02-计算球的体积 51Nod - 3266
对于半径为 rr 的球,其体积的计算公式为 V4/3πr3V4/3πr3 ,这里取 π3.14π3.14 。现给定 rr ,求 VV 。 Input 输入为一个不超过 100100 的非负实数,即球半径,类型为 doubledouble 。 Output 输出一个实数&#x…...
Qt pro文件详解
概述 在Qt中,.pro 文件(也称为项目文件)是Qt项目管理系统(qmake)所使用的配置文件。这个文件定义了如何构建你的Qt应用程序或库,其使用简单的键值对语法,允许你指定源文件、头文件、库依赖、配置…...
JavaFX布局-ButtonBar
JavaFX布局-ButtonBar 常用属性buttonOrderpaddingbuttonMinWidth 实现方式Java实现fxml实现 一个特殊的容器,用于创建一组按钮,水平排列按钮太多,会被遮住,不会自动产生滚动条 常用属性 buttonOrder 预制顺序 buttonBar.setBut…...
【C++程序设计】——利用数组处理批量数据(二)
👨💻个人主页:开发者-削好皮的Pineapple! 👨💻 hello 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨💻 本文由 削好皮的Pineapple! 原创 👨Ǵ…...
使用 1panel面板 部署 php网站
代码仓库:https://github.com/talmudmaster/RedCorpus 目录 网站介绍安装步骤1. 准备云服务器2. 准备域名(可跳过)3. 安装1panel面板4. 服务器开放端口5. 进入1panel面板6. 安装并启动软件(服务器和面板开放端口)7. 创…...
Windows调大虚拟内存来代替升级物理运行内存(RAM)真的有用吗?
前言 前段时间有个粉丝突发奇想说:电脑运行内存不足,调大虚拟内存来代替升级物理运行内存(内存条)不就可以了?剩下的大几百块钱吃香的喝辣的不好吗? 嗯。。。直到2024年的今天,估计还有很多小…...
网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...
nnUNet V2修改网络——暴力替换网络为UNet++
更换前,要用nnUNet V2跑通所用数据集,证明nnUNet V2、数据集、运行环境等没有问题 阅读nnU-Net V2 的 U-Net结构,初步了解要修改的网络,知己知彼,修改起来才能游刃有余。 U-Net存在两个局限,一是网络的最佳深度因应用场景而异,这取决于任务的难度和可用于训练的标注数…...
[拓扑优化] 1.概述
常见的拓扑优化方法有:均匀化法、变密度法、渐进结构优化法、水平集法、移动可变形组件法等。 常见的数值计算方法有:有限元法、有限差分法、边界元法、离散元法、无网格法、扩展有限元法、等几何分析等。 将上述数值计算方法与拓扑优化方法结合&#…...
AWS vs 阿里云:功能、服务与性能对比指南
在云计算领域,Amazon Web Services (AWS) 和阿里云 (Alibaba Cloud) 是全球领先的提供商,各自在功能范围、服务生态系统、性能表现和适用场景上具有独特优势。基于提供的引用[1]-[5],我将从功能、服务和性能三个方面进行结构化对比分析&#…...
CentOS 7.9安装Nginx1.24.0时报 checking for LuaJIT 2.x ... not found
Nginx1.24编译时,报LuaJIT2.x错误, configuring additional modules adding module in /www/server/nginx/src/ngx_devel_kit ngx_devel_kit was configured adding module in /www/server/nginx/src/lua_nginx_module checking for LuaJIT 2.x ... not…...
学习 Hooks【Plan - June - Week 2】
一、React API React 提供了丰富的核心 API,用于创建组件、管理状态、处理副作用、优化性能等。本文档总结 React 常用的 API 方法和组件。 1. React 核心 API React.createElement(type, props, …children) 用于创建 React 元素,JSX 会被编译成该函数…...
【笔记】结合 Conda任意创建和配置不同 Python 版本的双轨隔离的 Poetry 虚拟环境
如何结合 Conda 任意创建和配置不同 Python 版本的双轨隔离的Poetry 虚拟环境? 在 Python 开发中,为不同项目配置独立且适配的虚拟环境至关重要。结合 Conda 和 Poetry 工具,能高效创建不同 Python 版本的 Poetry 虚拟环境,接下来…...
