该文介绍如何利用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断路器.