SpringCloud集成Resilience4j实现熔断器

2023-11-14

前言

在文章《小谈Springcloud中的几个主流熔断器》我们介绍了SpingCloud架构中的几个主流熔断器,其中SpringCloud官方推荐的Resilience4j作为2020.x以后的新秀,远远没有hystrix有名,相关的文档也还不够多;今天这个文章就来讲讲SpringCloud如何使用Resilience4j实现熔断器;

Resilience4j

resilience4j是一个轻量级、易于使用的容错库,其灵感来自Netflixesilience4j是一个轻量级、易于使用的容错库,其灵感来自Netflix Hystrix,但专为Java 8和函数式编程设计。

Resilience4j提供高阶函数(decorators)来增强任何功能接口、lambda表达式或方法引用,包括断路器、速率限制器、重试或舱壁。可以在任何函数接口、lambda表达式或方法引用上使用多个装饰器。

Resilience4j非常轻量级,不仅可以在SpringCloud进行使用,还可以直接在自己的Java程序里通过Resilience4j的API实现Rate Limite的功能; 这点也是笔者非常认同的一点; 支持和扩展上更为方便; 今天的这个文章,重点还是介绍如何在SpringCloud里使用Resilicen4j

导入依赖包

通过pom.xml引入对Resilience4j的依赖

<dependency>
    <groupId>io.github.resilience4j</groupId>
    <artifactId>resilience4j-spring-boot</artifactId>
</dependency>

配置resilience4j

在项目的applicaiton.yml里添加SpringCloud里resilience4j的相关配置

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
        - java.util.concurrent.TimeoutException
        - java.io.IOException
      ignoreExceptions:
        - com.kxblive.common.error.CustomException
    shared:
      slidingWindowSize: 100
      permittedNumberOfCallsInHalfOpenState: 30
      waitDurationInOpenState: 1s
      failureRateThreshold: 50
      eventConsumerBufferSize: 10
      ignoreExceptions:
        - com.kxblive.common.error.CustomException
  instances:
    backendA:
      baseConfig: default
    backendB:
      registerHealthIndicator: true
      slidingWindowSize: 10
      minimumNumberOfCalls: 10
      permittedNumberOfCallsInHalfOpenState: 3
      waitDurationInOpenState: 5s
      failureRateThreshold: 50
      eventConsumerBufferSize: 10
      recordFailurePredicate: com.kxblive.common.error.FailureExceptionPredicate
resilience4j.retry:
  configs:
    default:
      maxAttempts: 3
      waitDuration: 100
      retryExceptions:
        - org.springframework.web.client.HttpServerErrorException
        - java.util.concurrent.TimeoutException
        - java.io.IOException
      ignoreExceptions:
        - com.kxblive.common.error.CustomException
  instances:
    backendA:
      baseConfig: default
    backendB:
      baseConfig: default
resilience4j.bulkhead:
  configs:
    default:
      maxConcurrentCalls: 100
  instances:
    backendA:
      maxConcurrentCalls: 10
    backendB:
      maxWaitDuration: 10ms
      maxConcurrentCalls: 20

resilience4j.thread-pool-bulkhead:
  configs:
    default:
      maxThreadPoolSize: 4
      coreThreadPoolSize: 2
      queueCapacity: 2
  instances:
    backendA:
      baseConfig: default
    backendB:
      maxThreadPoolSize: 1
      coreThreadPoolSize: 1
      queueCapacity: 1

resilience4j.ratelimiter:
  configs:
    default:
      registerHealthIndicator: false
      limitForPeriod: 10
      limitRefreshPeriod: 1s
      timeoutDuration: 0
      eventConsumerBufferSize: 100
  instances:
    backendA:
      baseConfig: default
    backendB:
      limitForPeriod: 6
      limitRefreshPeriod: 500ms
      timeoutDuration: 3s

resilience4j.timelimiter:
  configs:
    default:
      cancelRunningFuture: false
      timeoutDuration: 2s
  instances:
    backendA:
      baseConfig: default
    backendB:
      baseConfig: default

在这个配置中分别配置了circuitbeaker、retry、bulkhead、ratelimiter, timelimiter,thread-pool-bulkhead这些相关的熔断限流的相关项目。引入resilience4j-spring-boot集成了circuitbeaker、retry、bulkhead、ratelimiter几个模块的功能, 提供相关的实现;我们可以根据业务的实际需要对这些相关项目进行具体配置修改;

开发上和使用Hystrix大致上一样; 不过注意调整一下的地方

feign契约只能用feign的, 不能用SpringMVC的契约

feign契约只能用feign的, 不能用SpringMVC的契约;所以不能使用默认的方式,必须通过autoconfiguraiton进行修改

    @Bean
    public Contract feignContract(){
        return new Contract.Default();
    }

    /**
    @Bean
    public Contract feignContract(){
        return new SpringMvcContract();
    }
    **/

使用标准Feign注解

由于修改了feign的constract方式;所以默认的feign注解方式,不能使用SpringMVC的方式,必须使用Feign的标准方式

// after Hystrix is removed from SpringCloud2021.0.1, the fallback is ineffective
//@FeignClient(name = "${codeman.service.name:codeman}", url = "${codeman.service.address:}", fallback = CodeManFallbackImpl.class)
public interface CodeManFeign extends CodeManService {

    @RequestLine("GET /codeman/info/version")
    public String getVersion();

    @RequestLine("GET /codeman/info/author")
    public String getAuthor();

    @RequestLine("GET /codeman/info/author/{userid}")    //对应请求方式和路径
    public String requestLine(@Param("userid") String userid);
}

通过上面的代码可以看到在Feign的定义接口里, 不再使用SpringMVC里的标准Post/Get/Delete/Request等; 而是使用Feign标准的注解RequestLine;这个估计大多数做过Feign的朋友,还不知道这个才是Feign的标准Annotation; 由于上一步,我们修改了Consract不再使用SpringMVCConstract;所以Post/Get/Delete/Request等这些在SpringMVC里的Annotation不能使用;必须替换;

业务调用

上一段代码,我们定义出了RPC的remote调用接口;在service层,我们使用已定义的Feign接口,完成业务上的调用;

@Component
public class CodeManServiceImpl implements CodeManService{
    //@Autowired
    //CodeManFeign codeManFeign;

    @Value("${codeman.service.address:http://${codeman.service.name:codeman}}")
    private String url;

    @Value("${codeman.service.name:codeman}")
    private String name;

    CircuitBreaker circuitBreaker;
    CodeManFeign codeManFeign;

    @PostConstruct
    public void init(){
        circuitBreaker = CircuitBreaker.ofDefaults("backendA");

        FeignDecorators decorators = FeignDecorators.builder()
                .withFallback(new CodeManFallbackImpl(), FeignException.class)
                .build();

        codeManFeign = Resilience4jFeign.builder(decorators).target(new Target.HardCodedTarget<>(CodeManFeign.class,
                name, url));
    }

    @Override
    public String getVersion() {
        return codeManFeign.getVersion();
    }

    @Override
    public String getAuthor() {
        return codeManFeign.getAuthor();
    }

    @Override
    public String requestLine(String userid) {
        return codeManFeign.requestLine(userid);
    }
}

上面的业务调用的代码;和我们经常使用OpenFeign进行调用上有点差别;在与对CodeManFeign的IOC的获取上;可以看到代码里

注释掉了通过IOC的方式

//@Autowired

//CodeManFeign codeManFeign;

而是通过

@PostConstruct

public void init(){

}

的方式,在init里通过FeignDecorators.builder()去实例化了Resilience4jFeign.builder(decorators).target()的方式去实例化了这个; 这里也是不解的地方;为什么不去类似Hystrix的哦方式。在Feign接口定义的时候,也去做一些绑定,而是要手工在这里通过API进行绑定; 对这个不解:个人的感觉;可能还是在产品设计的时候,让这个设置更加的细化吧。

在我们自己的项目里,在这里是自己做了处理的,其实这个处理的目的就省略掉Init里的代码

定义Fallback的实现

public class CodeManFallbackImpl implements CodeManService {
    @Override
    public String getVersion() {
        return "N/A";
    }

    @Override
    public String getAuthor() {
        return "SpringCloud";
    }

    @Override
    public String requestLine(String userid){
        return "Kill team‘s poison";
    }
}

通过以上的步骤,就可以实现Resilience4j的熔断器的实现了。 题外话,由于我们自己的项目都是使用的springcloud来实现微服务;并且都是在springcloud的基础上结合公司项目的特点,封装了自己的springcloud的开发框架,在springcloud的ioc是个好东西,但是在spring里的ioc到处都是,不仅增加了调试问题和追踪问题的复杂程度;而且更让人不放心的就是ioc都是使用反射或者动态代理的方式进行处理的, 这样的实现方式真的存在着很大的隐患;不过由于我们使用SpringCloud实现的微服务大多数都是来处理业务应用,反射的性能低下相对于业务应用往往性能的瓶颈而言,基本上都可以忽略不计了,这样的隐患也就藏起来了。 当然在学习了go语言以后,深深的体会到了,做服务和做业务对设计模式的取舍点的不同;

 

结束语

本文主要介绍的是在SpringCloud微服务开发中,如何使用Resilience4j实现熔断器功能的实现方式; 也可以直接通过resilience4j的API,在自己的Java程序里实现熔断器功能, 说实在的,SpringCloud的微服务体系真的和Service Mesh的体系一比较,真的就是一个小孩和大人的比较,熔断是业务需求吗,既然不是,为什么springCloude的开发中,微服务的代码却要揉入熔断器的开发代码; 别扭吧; 这就是Service Mesh为什么会是未来的原因。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SpringCloud集成Resilience4j实现熔断器 的相关文章

  • 如何将 Java 赋值表达式转换为 Kotlin

    java中的一些东西就像 int a 1 b 2 c 1 if a b c System out print true 现在它应该转换为 kotlin 就像 var a Int 1 var b Int 2 var c Int 1 if a
  • ElasticBeanstalk Java,Spring 活动配置文件

    我正在尝试通过 AWS ElasticBeanstalk 启动 spring boot jar 一切正常 配置文件为 默认 有谁知道如何为 java ElasticBeanstalk 应用程序 不是 tomcat 设置活动配置文件 spri
  • 如何测试 JUnit 测试的 Comparator?

    我需要测试 Compare 方法 但我对如何测试感到困惑 我可以看看该怎么做吗 public class MemberComparator implements Comparator
  • 解决错误:日志已在具有多个实例的atomikos中使用

    我仅在使用atomikos的实时服务器上遇到问题 在我的本地服务器上它工作得很好 我在服务器上面临的问题是 init 中出错 日志已在使用中 完整的异常堆栈跟踪 java lang RuntimeException Log already
  • ExceptionConverter:java.io.IOException:文档没有页面。我正在使用 iText

    当我执行下面的代码时 File f new File c sample pdf PdfWriter getInstance document new FileOutputStream f document open System out p
  • 如何查找 Android 设备中的所有文件并将它们放入列表中?

    我正在寻求帮助来列出 Android 外部存储设备中的所有文件 我想查找所有文件夹 包括主文件夹的子文件夹 有办法吗 我已经做了一个基本的工作 但我仍然没有得到想要的结果 这不起作用 这是我的代码 File files array file
  • 使用 ANTLR 为 java 源代码生成抽象语法树

    如何使用 ANTLR 从 java src 代码生成 AST 有什么帮助吗 好的 步骤如下 前往ANTLR站点 http www antlr org 并下载最新版本 下载Java g和JavaTreeParser g文件来自here htt
  • HDFS:使用 Java / Scala API 移动多个文件

    我需要使用 Java Scala 程序移动 HDFS 中对应于给定正则表达式的多个文件 例如 我必须移动所有名称为 xml从文件夹a到文件夹b 使用 shell 命令我可以使用以下命令 bin hdfs dfs mv a xml b 我可以
  • Prim 的迷宫生成算法:获取相邻单元格

    我基于 Prim 算法编写了一个迷宫生成器程序 该算法是 Prim 算法的随机版本 从充满墙壁的网格开始 选择一个单元格 将其标记为迷宫的一部分 将单元格的墙壁添加到墙壁列表中 While there are walls in the li
  • Spring引导@Transactional

    spring boot会自动在controller层添加 Transactional注解吗 我尝试将 Transactional 放在服务层 但似乎控制器层覆盖了注释 我有这个配置
  • Java中接口作为方法参数

    前几天去面试 被问到了这样的问题 问 反转链表 给出以下代码 public class ReverseList interface NodeList int getItem NodeList nextNode void reverse No
  • 反思 Groovy 脚本中声明的函数

    有没有一种方法可以获取 Groovy 脚本中声明的函数的反射数据 该脚本已通过GroovyShell目的 具体来说 我想枚举脚本中的函数并访问附加到它们的注释 Put this到 Groovy 脚本的最后一行 它将作为脚本的返回值 a la
  • 如何在 JFreeChart TimeSeries 图表上显示降雨指数和温度?

    目前 我的 TimeSeries 图表每 2 秒显示一个位置的温度 现在 如果我想每2秒显示一次降雨指数和温度 我该如何实现呢 这是我的代码 import testWeatherService TestWeatherTimeLapseSer
  • 制作java包

    我的 Java 类组织变得有点混乱 所以我要回顾一下我在 Java 学习中跳过的东西 类路径 我无法安静地将心爱的类编译到我为它们创建的包中 这是我的文件夹层次结构 com david Greet java greeter SayHello
  • 将 JSON 参数从 java 发布到 sinatra 服务

    我有一个 Android 应用程序发布到我的 sinatra 服务 早些时候 我无法读取 sinatra 服务上的参数 但是 在我将内容类型设置为 x www form urlencoded 之后 我能够看到参数 但不完全是我想要的 我在
  • Netbeans 8 不会重新加载静态 Thymeleaf 文件

    我通过 Maven 使用 Spring Boot 和 Thymeleaf 当我进行更改时 我似乎无法让 Netbeans 自动重新部署我的任何 Thymeleaf 模板文件 为了看到更改 我需要进行完整的清理 构建 运行 这需要太长的时间
  • android Accessibility-service 突然停止触发事件

    我有一个 AccessibilityService 工作正常 但由于开发过程中的某些原因它停止工作 我似乎找不到这个原因 请看一下我的代码并告诉我为什么它不起作用 public class MyServicee extends Access
  • com.jcraft.jsch.JSchException:身份验证失败

    当我从本地磁盘上传文件到远程服务器时 出现这样的异常 com jcraft jsch JSchException Auth fail at org apache tools ant taskdefs optional ssh Scp exe
  • KeyPressed 和 KeyTyped 混淆[重复]

    这个问题在这里已经有答案了 我搜索过之间的区别KeyPressedand KeyTyped事件 但我仍然不清楚 我发现的一件事是 Keypressed 比 KeyTyped 首先被触发 请澄清一下这些事件何时被准确触发 哪个适合用于哪个目的
  • Swagger/Openapi-Annotations:如何使用 $ref 生成 allOf?

    我正在生成 Rest 端点 包括添加OpenAPI Swagger对生成的代码进行注释 虽然它对于基本类型运行得很好 但我在自定义类方面遇到了一些问题 现在我有很多自定义类的重复架构条目 使用 Schema 实现 MyClass class

随机推荐

  • [springboot 项目启动类Application.java运行没有任何反应]

    1 问题 最近从网上找了一个springboot项目学习 发现项目启动类无法运行 运行没有任何反应 maven依赖检查没有任何问题 2 解决方案 Files Setting Plugins Groovy勾选 再次运行 成功 3
  • Python: 装饰器和语法糖

    一 Python 装饰器 Python 装饰器本身就是一个函数 它的作用是装饰一个其他的函数 但是不改变原有的程序功能 还要增添新的功能 调用函数时的接口没有变化 比如 装修一个房子 如果不隔音 我在墙上加一层隔音板 却不能把墙拆了 换成隔
  • C# 关于浏览器——WebBrowser篇

    最近要写一个浏览器包裹一个网站 试了各种浏览器插件 记录一下 第一个就是微软的WebBrowser 这个很容易 直接拖过来 然后写一下注册表调用IE11的内核显示 这个代码是抄的
  • python金融数据分析马伟明_Python金融数据分析

    前言 第1章Python在金融中的应用 1 1Python适合我吗 1 1 1免费 开源 1 1 2高级 强大 灵活的编程语言 1 1 3丰富的标准库 1 2面向对象编程与函数式编程 1 2 1面向对象式方法 1 2 2函数式方法 1 2
  • docker day04

    Dockerfile FORM 1 指定基础镜像 可以起别名 也可以指定多个FROM指令 用于多阶段构建 2 加载触发器 加载ONBUILD指令 3 不指定基础镜像 声明当前镜像不依赖任何镜像 官方保留字 scratch RUN 1 在容器
  • 循序渐进,学会用pyecharts绘制瀑布图

    循序渐进 学会用pyecharts绘制瀑布图 瀑布图简介 瀑布图 Waterfall Plot 是由麦肯锡顾问公司所独创的图表类型 因为形似瀑布流水而称之为瀑布图 瀑布图采用绝对值与相对值结合的方式 适用于表达多个特定数值之间的数量变化关系
  • 串口调试助手与CH340驱动分享

    串口调试助手与CH340驱动分享 分享以下资源给大家 包括CH340与CH341驱动 野火以及正点原子的串口调试助手 网盘链接 链接 https pan baidu com s 1cARKBdzJhDcrQrBSfs2Nlw 提取码 fxv
  • python: PyCharm 2023.1打包项目成执行程序

    IDE 最底部 pyinstaller i heart ico D main py 生成成功
  • d指针在Qt上的应用及实现

    Qt为了使其动态库最大程度上实现二进制兼容 引入了d指针的概念 那么为什么d指针能实现二进制兼容呢 为了回答这个问题 首先弄清楚什么是二进制兼容 所谓二进制兼容动态库 指的是一个在老版本库下运行的程序 在不经过编译的情况下 仍然能够在新的版
  • Unity TimeLine循环播放某个时间段

    1 设置Playable Director的Update Method为GameTime模式 2 API using UnityEngine Playables 我们需要用到PlayableDirector的time属性 3 设置开始和结束
  • USB CDC 4G Module 调试问题总结

    USB CDC 4G Module ESP32S2 自定义开发板 SIM7600C1 其他按照github USB CDC 4G Module 使用说明 确保硬件正确SIM卡正常 编译注意做好在4 4版本下 配置过程注意运营商APN 编译没
  • python的编译器与解释器

    作者介绍 作者 小刘在C站 每天分享课堂笔记 一起努力 共赴美好人生 夕阳下 是最美的绽放 目录 一 为什么会有编译器和解释器 二 编译器和解释器的区别 三 python解释器种类 四 python的运行机制 一 为什么会有编译器和解释器
  • Java集合——Set详解

    前几天简单介绍了一下单列集合中的List 今天就给大家讲一下它的同胞兄弟Set的简介与使用情况 Set存取无序 元素唯一 代码演示 public static void demo1 HashSet
  • 各种排序算法详解集合(时间复杂度、空间复杂度、稳定性分析)

    动图来源 https blog csdn net weixin 41190227 article details 86600821 目录 一 冒泡排序 二 选择排序 三 插入排序 四 希尔排序 五 归并排序 六 快速排序 七 堆排序 八 计
  • Supermarket 【POJ - 1456】【并查集+哈希表思想+贪心】

    题目链接 原来 并查集还有这样的作用 题记 我想用个哈希表的思维来解这道题 但是 显然O N 2 的哈希表去查询并插入显然是不行的 那么既然挂在图论专题 我就得用相应的方式解答咯 要是不挂在图论专题 我可能会自闭了 我们对于每个物品按照价值
  • vue3实现前端导出Excel

    1 安装依赖 npm install xlsx 2 使用
  • 操作系统:进程调度模拟,C语言实现

    作业要求 题目要求 模拟实现进程调度的经典算法 包括FCFS SJF SPF HRRN和RR 时间片大小分别为1和4 输出调度过程 并计算不同调度算法的周转时间 平均周转时间 带权周转时间 平均带权周转时间 等待时间 平均等待时间等信息 实
  • RT-Thread之ENV工具

    快速索引 ENV工具简介 准备工作 1 Git 安装并设置环境变量 2 ENV 前往RT Thread官网下载 3 RTT源码 GitHub OSChina 云盘 ENV工具打开方式 scons 编译项目 1 进入 BSP 目录 选择 st
  • 计算二叉树的第k层中所有叶子结点个数

    计算二叉树的第k层中所有叶子结点个数 Time Limit 1000MS Memory Limit 65535K 题型 编程题 语言 无限制 描述 二叉链表表示的二叉树 按先序次序输入二叉树中结点的值 字符表示空树 构造二叉链表表示的二叉树
  • SpringCloud集成Resilience4j实现熔断器

    前言 在文章 小谈Springcloud中的几个主流熔断器 我们介绍了SpingCloud架构中的几个主流熔断器 其中SpringCloud官方推荐的Resilience4j作为2020 x以后的新秀 远远没有hystrix有名 相关的文档