强大!Spring Boot 3.3 实现弹性模式,轻松应对高并发挑战
在现代微服务架构中,随着系统的复杂性增加,服务间的依赖性也越来越高。在这种情况下,服务可能会受到不可预知的异常或故障影响,比如下游服务暂时不可用、网络延迟、资源争用等。这些问题可能导致请求失败,进而影响整个系统的稳定性。为了提升系统的容错能力和稳健性,我们通常会引入弹性模式(Resilience Patterns)。弹性模式通过容错和恢复机制,确保系统在遇到异常情况时能够优雅地降级或恢复,避免出现大规模宕机或雪崩效应。
弹性模式(Resilience Patterns)是一种设计和实现系统的策略,旨在提升系统在面对故障、异常或高负载时的稳定性和可靠性。它包括一系列设计模式和策略,通过这些策略可以有效地处理服务调用中的问题,减少系统故障对整体服务的影响
常见的弹性模式包括:
重试(Retry):在请求失败时,系统尝试重新发送请求,以便在瞬时故障或短暂网络问题消失后成功获取响应。
熔断器(Circuit Breaker):当系统检测到某个服务连续失败时,自动中断请求,以防止持续失败影响整个系统。
超时控制(Timeout):为防止服务响应时间过长,设置超时机制,确保不会无限等待请求响应。
回退(Fallback):在服务不可用时,返回预设的默认值或降级处理结果。
运行效果:
若想获取项目完整代码以及其他文章的项目源码,且在代码编写时遇到问题需要咨询交流,欢迎加入下方的知识星球。
接下来,我们将详细介绍如何在 Spring Boot 3.3 中结合 Resilience4j
来实现这些弹性模式,并展示如何通过前端 jquery
调用 JSON 接口实现重试功能。
项目依赖配置 (pom.xml)
我们首先配置项目依赖,pom.xml
文件中包含了 Resilience4j
、Lombok
和前端模板引擎 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提供了很大帮助,特别适合希望快速掌握企业级开发的开发人员。
今天就讲到这里,如果有问题需要咨询,大家可以直接留言或扫下方二维码来知识星球找我,我们会尽力为你解答。