
本指南将引导您使用 Spring Cloud 断路器完成将断路器应用于可能失败的方法调用的过程。
您将构建的内容
你将构建一个微服务应用程序,该应用程序使用断路器模式在方法调用失败时正常降级功能。使用断路器模式可以允许微服务在相关服务发生故障时继续运行,从而防止故障级联,并为故障服务提供恢复时间。
你需要什么
- 约15分钟
- 最喜欢的文本编辑器或 IDE
- JDK 1.8或以后
- 格拉德尔 4+或梅文 3.2+
- 您也可以将代码直接导入到 IDE 中:
如何完成本指南
像大多数春天一样入门指南,您可以从头开始并完成每个步骤,也可以绕过您已经熟悉的基本设置步骤。无论哪种方式,您最终都会得到工作代码。
要从头开始,请继续使用 Gradle 构建.
要跳过基础知识,请执行以下操作:
- 下载并解压缩本指南的源存储库,或使用吉特:
git clone https://github.com/spring-guides/gs-cloud-circuit-breaker.git
- 光盘成
gs-cloud-circuit-breaker/initial
- 跳转到设置服务器微服务应用程序.
完成后,您可以根据 中的代码检查结果。gs-cloud-circuit-breaker/complete
使用 Gradle 构建
使用 Maven 构建
使用 IDE 进行构建
设置服务器微服务应用程序
书店服务将具有单个终结点。它将在 上访问,并且(为简单起见)将返回推荐的阅读列表。/recommended
Mono
String
在 中编辑我们的主类。它应该看起来像这样:BookstoreApplication.java
bookstore/src/main/java/hello/BookstoreApplication.java
package hello;
import reactor.core.publisher.Mono;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
@RestController
@SpringBootApplication
public class BookstoreApplication {
@RequestMapping(value = "/recommended")
public Mono readingList(){
return Mono.just("Spring in Action (Manning), Cloud Native Java (O'Reilly), Learning Spring Boot (Packt)");
}
public static void main(String[] args) {
SpringApplication.run(BookstoreApplication.class, args);
}
}
注释标记为控制器类,就像 do 一样,并且还确保此类中的方法的行为就像使用 .也就是说,此类中方法的返回值将自动从其原始类型进行适当的转换,并将直接写入响应正文。@RestController
BookstoreApplication
@Controller
@RequestMapping
@ResponseBody
@RequestMapping
我们将在本地与客户端服务应用程序一起运行此应用程序,因此在 中设置,以便在我们运行该服务时 Bookstore 服务不会与客户端冲突。src/main/resources/application.properties
server.port
bookstore/src/main/resources/application.properties
设置客户端微服务应用程序
阅读应用程序将成为我们书店应用程序的前端(可以说是)。我们将能够在 上查看我们的阅读列表,并且该阅读列表将从书店服务应用程序中检索。/to-read
reading/src/main/java/hello/ReadingApplication.java
package hello;
import reactor.core.publisher.Mono;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.reactive.function.client.WebClient;
@RestController
@SpringBootApplication
public class ReadingApplication {
@RequestMapping("/to-read")
public Mono toRead() {
return WebClient.builder().build()
.get().uri("http://localhost:8090/recommended").retrieve()
.bodyToMono(String.class);
}
public static void main(String[] args) {
SpringApplication.run(ReadingApplication.class, args);
}
}
为了从Bookstore获取列表,我们使用Spring的类。 在我们提供时向书店服务的 URL 发出 HTTP GET 请求,然后将结果返回为 of 。(有关使用 Spring 使用 RESTful 服务的更多信息,请参阅WebClient
WebClient
Mono
String
WebClient
构建一个反应式 RESTful Web 服务指南。
将属性添加到 :server.port
src/main/resources/application.properties
reading/src/main/resources/application.properties
现在,我们可以在浏览器中访问阅读应用程序上的端点,并查看我们的阅读列表。然而,由于我们依赖 Bookstore 应用程序,如果它发生任何事情,或者如果 Reading 根本无法访问 Bookstore,我们将没有列表,我们的用户将收到一条讨厌的 HTTP 错误消息。/to-read
500
应用断路器模式
Spring Cloud 的断路器库提供了断路器模式的实现:当我们在断路器中包装方法调用时,Spring Cloud 断路器会监视对该方法的失败调用,如果故障累积到阈值,Spring Cloud 断路器会打开电路,以便后续调用自动失败。当电路打开时,Spring Cloud 断路器会将调用重定向到该方法,并将它们传递给我们指定的回退方法。
Spring Cloud Circuit Breaker支持许多不同的断路器实现,包括Resilience4J,Hystrix,Sentinal和Spring Retry。在本指南中,我们将使用 Resilience4J 实现。要使用此实现,我们只需要添加到应用程序的类路径中。spring-cloud-starter-circuitbreaker-reactor-resilience4j
reading/pom.xml
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
hello
reading-complete
0.0.1-SNAPSHOT
jar
org.springframework.boot
spring-boot-starter-parent
3.0.0
UTF-8
17
org.springframework.cloud
spring-cloud-starter-circuitbreaker-reactor-resilience4j
org.springframework.boot
spring-boot-starter-webflux
org.springframework.boot
spring-boot-starter-test
test
org.springframework.cloud
spring-cloud-dependencies
2020.0.3
pom
import
org.springframework.boot
spring-boot-maven-plugin
spring-snapshots
Spring Snapshots
https://repo.spring.io/libs-snapshot-local
true
spring-milestones
Spring Milestones
https://repo.spring.io/libs-milestone-local
false
spring-releases
Spring Releases
https://repo.spring.io/release
false
reading/build.gradle
buildscript {
ext {
springBootVersion = '3.0.0'
}
repositories {
mavenCentral()
maven { url 'https://repo.spring.io/milestone' }
maven { url 'https://repo.spring.io/snapshot' }
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
bootJar {
baseName = 'reading'
version = '0.0.1-SNAPSHOT'
}
sourceCompatibility = 17
targetCompatibility = 17
repositories {
mavenCentral()
}
dependencies {
implementation('org.springframework.cloud:spring-cloud-starter-circuitbreaker-reactor-resilience4j')
implementation('org.springframework.boot:spring-boot-starter-webflux')
testImplementation('org.springframework.boot:spring-boot-starter-test')
}
ext {
set('springCloudVersion', "2020.0.3")
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
eclipse {
classpath {
containers.remove('org.eclipse.jdt.launching.JRE_CONTAINER')
containers 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8'
}
}
Spring Cloud 断路器提供了一个称为的接口,我们可以使用它为我们的应用程序创建新的断路器。此接口的实现将根据应用程序类路径上的起始器自动配置。让我们创建一个使用此接口对书店应用程序进行 API 调用的新服务ReactiveCircuitBreakerFactory
reading/src/main/java/hello/BookService.java
package hello;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.publisher.Mono;
import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreaker;
import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreakerFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
@Service
public class BookService {
private static final Logger LOG = LoggerFactory.getLogger(BookService.class);
private final WebClient webClient;
private final ReactiveCircuitBreaker readingListCircuitBreaker;
public BookService(ReactiveCircuitBreakerFactory circuitBreakerFactory) {
this.webClient = WebClient.builder().baseUrl("http://localhost:8090").build();
this.readingListCircuitBreaker = circuitBreakerFactory.create("recommended");
}
public Mono readingList() {
return readingListCircuitBreaker.run(webClient.get().uri("/recommended").retrieve().bodyToMono(String.class), throwable -> {
LOG.warn("Error making request to book service", throwable);
return Mono.just("Cloud Native Java (O'Reilly)");
});
}
}
有一个叫做我们可以用来创建新的断路器的方法。一旦我们有了断路器,我们所要做的就是打电话 .运行需要 or 和可选的 .可选参数在出现任何问题时充当我们的回退。在我们的示例中,回退将只返回包含 .ReactiveCircuitBreakerFactory
create
run
Mono
Flux
Function
Function
Mono
String
Cloud Native Java (O’Reilly)
使用我们的新服务后,我们可以更新代码以使用此新服务。ReadingApplication
reading/src/main/java/hello/ReadingApplication.java
package hello;
import reactor.core.publisher.Mono;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.reactive.function.client.WebClient;
@RestController
@SpringBootApplication
public class ReadingApplication {
@Autowired
private BookService bookService;
@RequestMapping("/to-read")
public Mono toRead() {
return bookService.readingList();
}
public static void main(String[] args) {
SpringApplication.run(ReadingApplication.class, args);
}
}
试试看
同时运行书店服务和阅读服务,然后在 打开阅读服务的浏览器。您应该会看到完整的推荐阅读列表:localhost:8080/to-read
Spring in Action (Manning), Cloud Native Java (O'Reilly), Learning Spring Boot (Packt)
现在关闭书店应用程序。我们的列表来源已经消失,但多亏了 Hystrix 和 Spring Cloud Netflix,我们有一个可靠的缩写列表来填补空白;您应该看到:
Cloud Native Java (O'Reilly)
总结
祝贺!您刚刚开发了一个 Spring 应用程序,该应用程序使用断路器模式来防止级联故障,并为可能失败的调用提供回退行为。