ITPub博客

首页 > 数据库 > 数据库开发技术 > Spring Boot集成Resilience4J实现断路器功能

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

原创 数据库开发技术 作者:hblog 时间:2024-08-02 23:49:00 0 删除 编辑

1.什么是Resilience4J?

Netflix Hystrix 断路器是 Spring Cloud 中最早就开始支持的一种服务调用容错解决方案,但是目前的 Hystrix 已经处于维护模式了,虽然这并不影响已经上线的项目,并且在短期内,你甚至也可以继续在项目中使用 Hystrix 。但是长远来看,处于维护状态的 Hystrix 走下历史舞台只是一个时间问题,特别是在 Spring Cloud Greenwich 版中,官方已经给出了 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")@RestControllerpublic 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@Datapublic 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;
@SpringBootApplicationpublic 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.引用

  • https://docs.spring.io/spring-cloud-commons/docs/current/reference/html/#spring-cloud-circuit-breaker


原文作者:HBLOG;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2022-05-04

  • 博文量
    210
  • 访问量
    111762