该文介绍如何利用Spring Cloud网关将resilience4j断路器与网关后面的后端服务结合使用,方法如下:
整个代码示例在 github中 。
需要向您的Spring Cloud Gateway应用程序添加以下依赖项,以启用Resilience4j断路器集成:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot2</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-circuitbreaker-reactor-resilience4j</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
后端服务路由配置,如下所示:
spring:
application:
name: gateway-service
output.ansi.enabled: ALWAYS
cloud:
gateway:
routes:
- id: test-service-withResilient4j
uri: http:<font><i>//localhost:8091</i></font><font>
predicates:
- Path=/testService</font><font><i>/**
filters:
- RewritePath=/testService/(?<path>.*), /$/{path}
</i></font>
现在,Spring Cloud断路器starter允许您通过Customizer用法来配置Resilience4j断路器定义,这是代码优先的方法(通过代码进行定制是默认优先,而不是通过配置定制),但是如果要对其从外部进行配置,这样可以通过分布式配置服务从外部控制其配置,那么就使用Resilience4j spring boot starter发挥作用,它使断路器的外部SpringBoot配置成为可能。
Resilience4j的Spring Boot Starter将根据您的外部配置创建CircuitBreakerRegistery bean,然后您可以将其注入Spring Cloud Starter的resilience4j工厂以实现集成,就是这样!
Resilience4j的外部配置将类似于:
resilience4j.circuitbreaker:
configs:
default:
slidingWindowSize: 10
minimumNumberOfCalls: 5
permittedNumberOfCallsInHalfOpenState: 3
automaticTransitionFromOpenToHalfOpenEnabled: true
waitDurationInOpenState: 2s
failureRateThreshold: 50
eventConsumerBufferSize: 10
recordExceptions:
- org.springframework.web.client.HttpServerErrorException
- java.io.IOException
ignoreExceptions:
- java.lang.IllegalStateException
shared:
slidingWindowSize: 100
permittedNumberOfCallsInHalfOpenState: 30
waitDurationInOpenState: 1s
failureRateThreshold: 50
eventConsumerBufferSize: 10
ignoreExceptions:
- java.lang.IllegalStateException
instances:
backendA:
baseConfig: default
backendB:
slidingWindowSize: 10
minimumNumberOfCalls: 10
permittedNumberOfCallsInHalfOpenState: 3
waitDurationInOpenState: 1s
failureRateThreshold: 50
eventConsumerBufferSize: 10
加载Resilience4j的断路器注册表与Spring Cloud ReactiveResilience4JCircuitBreakerFactory之间的集成将如下进行:
@Bean
public ReactiveResilience4JCircuitBreakerFactory reactiveResilience4JCircuitBreakerFactory(CircuitBreakerRegistry circuitBreakerRegistry) {
ReactiveResilience4JCircuitBreakerFactory reactiveResilience4JCircuitBreakerFactory = new ReactiveResilience4JCircuitBreakerFactory();
reactiveResilience4JCircuitBreakerFactory.configureCircuitBreakerRegistry(circuitBreakerRegistry);
return reactiveResilience4JCircuitBreakerFactory;
}
现在是时候测试该集成并查看其工作原理:
添加以下依赖项以启用模拟Mock服务器的使用:
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>mockserver</artifactId>
<version>1.12.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mock-server</groupId>
<artifactId>mockserver-client-java</artifactId>
<version>3.10.8</version>
<scope>test</scope>
</dependency>
现在,您需要配置测试容器starup,并在模拟服务器启动后注入路由的自定义配置:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@RunWith(SpringRunner.class)
@ContextConfiguration(initializers = {GatewayCircuitBreakerTest.Initializer.class})
public class GatewayCircuitBreakerTest {
private static final Logger LOGGER = LoggerFactory.getLogger(GatewayCircuitBreakerTest.class);
private static MockServerContainer mockServerContainer;
static {
mockServerContainer = new MockServerContainer();
mockServerContainer.start();
}
static class Initializer
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
TestPropertyValues.of(
"spring.cloud.gateway.routes[0].id=test-service-withResilient4j",
"spring.cloud.gateway.routes[0].uri=" + mockServerContainer.getEndpoint(),
"spring.cloud.gateway.routes[0].predicates[0]=" + "Path=/testService/**",
"spring.cloud.gateway.routes[0].filters[0]=" + "RewritePath=/testService/(?<path>.*), /$//{path}",
"spring.cloud.gateway.routes[0].filters[1].name=" + "CircuitBreaker",
"spring.cloud.gateway.routes[0].filters[1].args.name=" + "backendA",
"spring.cloud.gateway.routes[0].filters[1].args.fallbackUri=" + "forward:/fallback/testService"
).applyTo(configurableApplicationContext.getEnvironment());
}
}
private MockServerClient client = new MockServerClient(mockServerContainer.getContainerIpAddress(), mockServerContainer.getServerPort());
@Autowired
private TestRestTemplate template;
@AfterClass
public static void close(){
mockServerContainer.close();
}
}
最后,您可以在类 GatewayCircuitBreakerTest中 触发受保护端点的测试,并通过分析控制台中报告的事件来查看它正在通过Resilience4j断路器.