强大!Spring Boot 3.3 实现弹性模式,轻松应对高并发挑战

科技   2024-10-06 07:30   河北  


强大!Spring Boot 3.3 实现弹性模式,轻松应对高并发挑战

在现代微服务架构中,随着系统的复杂性增加,服务间的依赖性也越来越高。在这种情况下,服务可能会受到不可预知的异常或故障影响,比如下游服务暂时不可用、网络延迟、资源争用等。这些问题可能导致请求失败,进而影响整个系统的稳定性。为了提升系统的容错能力和稳健性,我们通常会引入弹性模式(Resilience Patterns)。弹性模式通过容错和恢复机制,确保系统在遇到异常情况时能够优雅地降级或恢复,避免出现大规模宕机或雪崩效应。

弹性模式(Resilience Patterns)是一种设计和实现系统的策略,旨在提升系统在面对故障、异常或高负载时的稳定性和可靠性。它包括一系列设计模式和策略,通过这些策略可以有效地处理服务调用中的问题,减少系统故障对整体服务的影响

常见的弹性模式包括:

  • 重试(Retry):在请求失败时,系统尝试重新发送请求,以便在瞬时故障或短暂网络问题消失后成功获取响应。

  • 熔断器(Circuit Breaker):当系统检测到某个服务连续失败时,自动中断请求,以防止持续失败影响整个系统。

  • 超时控制(Timeout):为防止服务响应时间过长,设置超时机制,确保不会无限等待请求响应。

  • 回退(Fallback):在服务不可用时,返回预设的默认值或降级处理结果。

运行效果:

若想获取项目完整代码以及其他文章的项目源码,且在代码编写时遇到问题需要咨询交流,欢迎加入下方的知识星球。

接下来,我们将详细介绍如何在 Spring Boot 3.3 中结合 Resilience4j 来实现这些弹性模式,并展示如何通过前端 jquery 调用 JSON 接口实现重试功能。

项目依赖配置 (pom.xml)

我们首先配置项目依赖,pom.xml 文件中包含了 Resilience4jLombok 和前端模板引擎 Thymeleaf 等相关依赖。

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.icoderoad</groupId>
<artifactId>resilience-patterns</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>resilience-patterns</name>
<description>Demo project for Spring Boot</description>

<properties>
<java.version>17</java.version>
</properties>
<dependencies>

<!-- Spring Boot Starter Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- Resilience4j 依赖 -->
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot3</artifactId>
<version>2.0.2</version>
</dependency>

<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>

<!-- Thymeleaf -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

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

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>

application.yaml 配置

在 application.yaml 文件中,定义 Resilience4j 的重试和超时策略配置。

resilience:
retry:
maxAttempts: 5 # 最大重试次数,适用于高并发场景
timeout:
duration: 2000 # 超时时间,单位毫秒
circuitbreaker:
failureRateThreshold: 50 # 失败率阈值,超过此值将触发熔断
waitDurationInOpenState: 10000 # 熔断后等待 10 秒再尝试恢复

配置类 ResilienceConfig.java

通过 @ConfigurationProperties 注解将配置文件中的弹性参数映射为 Java 类属性,Lombok用于自动生成 getter 和 setter 方法。

package com.icoderoad.resilience.patterns;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Data
@Configuration
@ConfigurationProperties(prefix = "resilience")
public class ResilienceProperties {
private Retry retry;
private Timeout timeout;
private CircuitBreaker circuitbreaker;

@Data
public static class Retry {
private int maxAttempts;
}

@Data
public static class Timeout {
private int duration;
}

@Data
public static class CircuitBreaker {
private int failureRateThreshold;
private int waitDurationInOpenState;
}
}

服务层 ResilienceService.java

服务层实现中使用了 Resilience4j 的 Retry 和 TimeLimiter 注解,实现重试和超时机制。

package com.icoderoad.resilience.patterns.service;

import io.github.resilience4j.retry.annotation.Retry;
import io.github.resilience4j.timelimiter.annotation.TimeLimiter;
import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import org.springframework.stereotype.Service;

import java.util.concurrent.CompletableFuture;

@Service
public class ResilienceService {

@Retry(name = "backendA", fallbackMethod = "fallback")
@CircuitBreaker(name = "backendA")
@TimeLimiter(name = "backendA")
public CompletableFuture<String> performOperation() {
return CompletableFuture.supplyAsync(() -> {
simulateLongRunningProcess();
return "操作成功!";
});
}

private void simulateLongRunningProcess() {
try {
Thread.sleep(3000); // 模拟超时
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}

// 回退逻辑
public CompletableFuture<String> fallback(Throwable t) {
return CompletableFuture.supplyAsync(() -> "操作失败,已进入回退逻辑!");
}
}

控制器 ResilienceController.java

控制器中新增了 JSON 接口 resilience/json,供前端通过 jquery 调用,并返回 JSON 格式的响应结果。

package com.icoderoad.resilience.patterns.service.controller;

import java.util.concurrent.ExecutionException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.icoderoad.resilience.patterns.service.ResilienceService;

@RestController
@RequestMapping("/resilience")
public class ResilienceController {

@Autowired
private ResilienceService resilienceService;

@GetMapping("/json")
public String resilienceTestJson() throws ExecutionException, InterruptedException {
return resilienceService.performOperation().get();
}
}

前端页面 resilience.html

前端页面使用 Thymeleaf 渲染,同时使用 jquery 调用后端的 JSON 接口,动态展示结果并提供重试按钮。页面使用 Bootstrap 样式显示响应结果和提示信息。

在 src/main/resources/templates/index.html 文件中使用 Thymeleaf 模板显示配置信息:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>弹性模式测试</title>
<!-- Bootstrap CDN -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
</head>
<body>
<div class="container mt-5">
<h2>弹性模式测试</h2>
<div id="responseResult" class="alert alert-info" role="alert">
结果将在此显示...
</div>

<button id="retryButton" class="btn btn-primary">重试</button>
</div>

<!-- jQuery CDN -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<!-- Bootstrap JS CDN -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>

<script>
$(document).ready(function () {
$('#retryButton').click(function () {
$.get('/resilience/json', function (data) {
$('#responseResult').html(data);
$('#responseResult').removeClass('alert-info').addClass('alert-success');
}).fail(function () {
$('#responseResult').html("请求失败,请稍后再试!");
$('#responseResult').removeClass('alert-success').addClass('alert-danger');
});
});
});
</script>
</body>
</html>

结论

通过本文的实现,我们展示了如何在 Spring Boot 3.3 中结合 Resilience4j 实现弹性模式(包括重试、熔断器和超时控制等)。我们还通过 jquery 调用 JSON 接口实现了重试功能,并使用了 Bootstrap 提供的提示样式。通过这些措施,系统能够在面对不稳定的服务调用时更加稳健,确保在遇到服务故障时,能够通过优雅的降级和回退机制保持核心功能的可用性。

这种实现方式为微服务系统提供了一个可靠的解决方案,在面对故障和不可预知的网络问题时,可以有效提升系统的容错性和可扩展性。


在我编写Spring Boot 3.x相关技术文章的过程中,许多核心内容和技术实现都参考了《深入浅出Spring Boot 3.x》这本书。该书深入浅出地讲解了Spring Boot 3.x的各项关键技术,涵盖了Spring全注解配置、数据库编程(JPA、MyBatis、JDBC)、事务管理、NoSQL数据库(如Redis和MongoDB),以及Spring MVC、REST API开发等内容。书中还结合了当前互联网业务场景,探讨了抢购业务、微服务架构(Spring Cloud Alibaba)、系统监控和容器部署等实战项目,是我在文章中引用的重要技术依据。这本书对深入理解和运用Spring Boot 3.x提供了很大帮助,特别适合希望快速掌握企业级开发的开发人员。



今天就讲到这里,如果有问题需要咨询,大家可以直接留言或扫下方二维码来知识星球找我,我们会尽力为你解答。


AI资源聚合站已经正式上线,该平台不仅仅是一个AI资源聚合站,更是一个为追求知识深度和广度的人们打造的智慧聚集地。通过访问 AI 资源聚合网站 https://ai-ziyuan.techwisdom.cn/,你将进入一个全方位涵盖人工智能和语言模型领域的宝藏库


作者:路条编程(转载请获本公众号授权,并注明作者与出处)

路条编程
路条编程是一个友好的社区,在这里你可以免费学习编程技能,我们旨在激励想学编程的人尝试新的想法和技术,在最短的时间学习到工作中使用到的技术!
 最新文章