Spring Boot集成Resilience4J实现断路器功能

news2024/9/20 20:37:01

1.什么是Resilience4J?

Netflix Hystrix 断路器是 Spring Cloud 中最早就开始支持的一种服务调用容错解决方案,但是目前的 Hystrix 已经处于维护模式了,虽然这并不影响已经上线的项目,并且在短期内,你甚至也可以继续在项目中使用 Hystrix 。但是长远来看,处于维护状态的 Hystrix 走下历史舞台只是一个时间问题,特别是在 Spring Cloud Greenwich 版中,官方已经给出了 Hystrix 的建议替代方案。如下图:

660329-20200912073853847-1594925749

Resilience4j 是 Spring Cloud Greenwich 版推荐的容错解决方案,它是一个轻量级的容错库,受 Netflix Hystrix 的启发而设计,它专为 Java 8 和函数式编程而设计。 Resilience4j 非常轻量级,因为它的库只使用 Vavr (以前称为 Javaslang ),它没有任何其他外部库依赖项。相比之下, Netflix Hystrix 对Archaius 具有编译依赖性,这导致了更多的外部库依赖,例如 Guava 和 Apache Commons 。而如果使用Resilience4j,你无需引用全部依赖,可以根据自己需要的功能引用相关的模块即可。 Resilience4j 也提供了一系列增强微服务可用性的功能,主要功能如下:

  • 断路器
  • 限流
  • 基于信号量的隔离
  • 缓存
  • 限时
  • 请求重试

今天我么主要讲解断路器是如何实现的?

2.实验工程

实验目的

实现断路器功能

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.1</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>resilience4j</artifactId>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
    </properties>
    <dependencies>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <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>

    </dependencies>
</project>

controller

package com.et.resilience4j.controller;

import com.et.resilience4j.model.Activity;
import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@Slf4j
@RequestMapping("/activity")
@RestController
public class ActivityController {

    private RestTemplate restTemplate;

    private final String BORED_API = "http://www.liuhaihua.cn/api/activity";

    public ActivityController(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    @GetMapping
    @CircuitBreaker(name = "randomActivity", fallbackMethod = "fallbackRandomActivity")
    public String getRandomActivity() {
        ResponseEntity<Activity> responseEntity = restTemplate.getForEntity(BORED_API, Activity.class);
        Activity activity = responseEntity.getBody();
        log.info("Activity received: " + activity.getActivity());
        return activity.getActivity();
    }

    public String fallbackRandomActivity(Throwable throwable) {
        return "fail to read a Activity from HBLOG";
    }

}

entity

package com.et.resilience4j.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/* sample message
    {
        "activity": "Start a family tree",
            "type": "social",
            "participants": 1,
            "price": 0,
            "link": "https://en.wikipedia.org/wiki/Family_tree",
            "key": "6825484",
            "accessibility": 1
    }*/
@NoArgsConstructor
@AllArgsConstructor
@Data
public class Activity {
    private String activity;
    private String type;
    private String link;
    private String key;
    private Integer participants;
    private Double price;
    private Double accessibility;
}

DemoApplication.java

package com.et.resilience4j;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
public class DemoApplication {

   public static void main(String[] args) {
      SpringApplication.run(DemoApplication.class, args);
   }

   @Bean
   public RestTemplate restTemplate() {
      return new RestTemplate();
   }

}

application.yaml

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

以上只是一些关键代码,所有代码请参见下面代码仓库

代码仓库

  • https://github.com/Harries/springboot-demo(Resilience4J)

3.测试

  • 启动Spring Boot应用工程
  • 访问http://127.0.0.1:8080/activity
  • 返回fail to read a Activity from HBLOG

4.引用

  • Cloud Native Applications

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1972904.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【AD域】搭建AD域服务器

环境 服务器&#xff1a;Windows Server 2016 Standard&#xff0c;版本1607 准备 1、设置主机名 2、配置静态IP地址 3、以本地管理员权限登录服务器 步骤 1、在服务器添加【Active Directory】域服务功能 2、AD域服务器配置

ERP系统提高生产企业库存周转率的抓手

引言 生产企业库存积压&#xff0c;有市场波动的原因&#xff0c;也有内部管理的原因。常见的内部管理原因有&#xff1a; 物料买多了&#xff0c;长期积压在仓库 缺料&#xff0c;生产不能及时完工&#xff0c;在制品积压 物料买早了&#xff0c;在仓库呆滞时间过长 在ERP…

RIP路由协议之网络工程师软考中级

几种常见的路由协议 路由协议名称路由协议分类&#xff08;工作原理&#xff09;协议分类&#xff08;工作区域&#xff09;路由算法RIP距离矢量IGPBellman-FordOSPF-ISIS链路状态IGPDijkstraBGP路径向量EGP/ IGP称为内部网关协议&#xff08;I人&#xff0c;内向&#xff09…

瑞芯微Android设备指定应用开启性能模式

本文档主要针对特定应用&#xff08;如 安兔兔&#xff09;如何进行加速及性能的提升做相关说明。 快速开启方法 开启与关闭 在 device/rockchip/rk3xxx/下配置文件:package_performance.xml&#xff0c;在其中的节点中加入需要使用性能模式的包名&#xff1a;&#xff08;…

Java零基础之多线程篇:如何保证线程安全?

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一…

使用swiftui自定义圆形进度条实现loading

实现的代码如下&#xff1a; // // LoadingView.swift // SwiftBook // // Created by Song on 2024/8/2. //import SwiftUIstruct LoadingView: View {State var process 0.5var body: some View {VStack(spacing: 20) {ZStack {Circle().stroke(.gray.opacity(0.3), lin…

【QGroundControl二次开发】八. QT实现播放gstreamer视频

上篇写到如何搭建gstreamer在Windows和linux下的环境&#xff0c;以及新建VS工程解码视频流。gstreamer 配置解析编解码 本篇主要讲述c源码移植到QT工程。 一. QT工程配置 gstreamer环境参考上面链接。 在项目的.pro文件中加入如下代码。&#xff08;以linux项目为例&#xff…

【Python 逆向滑块】(实战四)逆向滑块,并实现用Python+Node.js 生成滑块、识别滑块、验证滑块、发送短信

逆向日期&#xff1a;2024.08.02 使用工具&#xff1a;python、Node.js 本章知识&#xff1a;逆向网易易盾【data】参数里的【d】【p】【f】【ext】参数 文章难度&#xff1a;中等&#xff08;没耐心的请离开&#xff09; 文章全程已做去敏处理&#xff01;&#xff01;&#x…

物理学是研究‘’物质一般的运动规律‘’和‘’物质基本结构‘’的自然科学

物理学是一门研究物质最一般的运动规律和物质基本结构的自然科学学科。作为自然科学的带头学科&#xff0c;物理学研究大至宇宙&#xff0c;小至基本粒子等一切物质最基本的运动形式和规律&#xff0c;因此成为其他各自然科学学科的研究基础。 以下是对物理学的详细解析&#x…

儿童安全门和围栏美国CPC认证ASTM F1004测试16CFR1239测试

什么是儿童安全门和围栏&#xff1f; ASTM F1004-22将“伸缩门”定义为“旨在安装在门口等开口处的障碍物&#xff0c;以防止儿童通过&#xff0c;但可以由能够操作锁定装置的老年人拆除”(第3.1.7节)。 ASTM F1004-22将“可扩展围栏”定义为“旨在完全包围幼儿可能被限制在其…

数据结构与算法--栈

文章目录 知识回顾顺序存储结构的优缺点链式存储结构的优缺点 数据结构的三个方面栈的定义与特点栈的基本运算栈的存储结构与实现顺序栈入栈操作出栈操作 链栈入栈操作入栈操作 栈的应用数制转换表达式求值中缀表达式向后缀表达式的转换后缀表达式的求值过程 总结 知识回顾 顺…

Telnet和SSH配置学习笔记

1. Telnet应用场景 为方便通过命令行管理设备&#xff0c;可以使用Telnet协议对设备进行管理。 Telnet协议与使用Console接口管理设备不同&#xff0c;无需专用线缆直连设备的Console接口&#xff0c;只要IP地址可达、能够和设备的TCP 23端口通信即可。 支持通过Telnet协议进…

Redis基础总结、持久化、主从复制、哨兵模式、内存淘汰策略、缓存

文章目录 Redis 基础Redis 是什么&#xff0c;有哪些特点为什么要使用 Redis 而不仅仅依赖 MySQLRedis 是单线程吗Redis 单线程为什么还这么快 Redis 数据类型和数据结构五种基本数据结构及应用场景其他数据类型Redis 底层数据结构 Redis 持久化数据不丢失的实现AOF 日志RDB 快…

如何理解复信号z的傅里叶变换在频率v<0的时候恒为0,是解析信号

考虑例子2.12.1的说法。 首先我尝试解释第二个说法。需要注意一个事实是 实函数f的傅里叶变换F的实部是偶函数&#xff0c;虚部是奇函数。如图所示&#xff1a; 注意的是这个图中虽然是离散傅里叶变换的性质&#xff0c;但是对于一般的傅里叶变换的性质是适用的。 推导过程如下…

Tecplot安装error找不到指定模块之解决方案

最近有小伙伴反应&#xff0c;在安装Tecplot 2023版本时&#xff0c;参考教程来操作很顺利&#xff0c;但是在开启软件后&#xff0c;有一个error弹窗&#xff0c;内容如下&#xff1a; 随后用中英文翻译&#xff1a;找不到指定模块 同时&#xff0c;软件内部的Tool工具栏打不…

液位传感器- 从零开始认识各种传感器【二十四期】

液位传感器|从零开始认识各种传感器 1、什么是液位传感器 &#xff1f; 液位传感器是一种用于检测和测量液体位置和高度的装置&#xff0c;广泛应用于工业、农业、环保和家庭等领域。液位传感器可以实时监测液体的水平&#xff0c;以实现自动化控制和安全防护。 2、液位传感器…

java之方法引用 —— ::

目录 一、简介 二、引用静态方法 1.格式 2.示例 ​编辑 3.条件解析 三、引用成员方法 1.格式 2.示例 四、引用构造方法 1.格式 2.示例 五、类名引用成员方法 1.格式 2.略微不同的方法引用规则 3.示例 六、引用数组的构造方法 1.格式 2.示例 一、简介 方…

C语言笔记39 •数据结构--栈队列-OJ•

栈&队列-OJ 1.给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; (1).左括号必须用相同类型的右括号闭合。 (2).左括号必须以正确的顺序闭合。 (3).每个右括…

MQ消息队列篇:三大MQ产品的必备面试种子题

MQ有什么用&#xff1f; MQ&#xff08;消息队列&#xff09;是一种FIFO&#xff08;先进先出&#xff09;的数据结构&#xff0c;主要用于实现异步通信、削峰平谷和解耦等功能。它通过将生产者生成的消息发送到队列中&#xff0c;然后由消费者进行消费。这样&#xff0c;生产…

【Kubernetes】k8s集群中kubectl的陈述式资源管理

目录 一.k8s集群资源管理方式分类 1.陈述式资源管理方式 2.声明式资源管理方式 二.陈述式资源管理方法 三.kubectl命令 四.项目生命周期 1.创建 kubectl create命令 2.发布 kubectl expose命令 3.更新 kubectl set 4.回滚 kubectl rollout 5.删除 k…