Spring Cloud Gateway配置CircuitBreaker 一般会用到如下2种GatewayFilter Factory:
- Hystrix GatewayFilter Factory
- Spring Cloud CircuitBreaker GatewayFilter Factory
其中使用Hystrix GatewayFilter Factory需要依赖spring-cloud-starter-netflix-hystrix。而netflix-hystrix可能以后不再有更新了,所以推荐使用Spring Cloud CircuitBreaker GatewayFilter Factory。
如果使用Hystrix GatewayFilter Factory,application.yml中可以采用如下方式分别配置:
spring:
cloud:
gateway:
routes:
- id: ingredients
uri: lb://ingredients
predicates:
- Path=//ingredients/**
filters:
- name: Hystrix
args:
name: fetchIngredients
fallbackUri: forward:/fallback
- id: ingredients-fallback
uri: http://localhost:9994
predicates:
- Path=/fallback
以下将以Spring Cloud CircuitBreaker GatewayFilter Factory来说明如何配置CircuitBreaker。
Spring Cloud CircuitBreaker API是对多种断路器提供的一层抽象API,Spring Cloud CircuitBreaker本身提供了对4种断路器组件的支持:
- Netfix Hystrix
- Resilience4J
- Sentinel
- Spring Retry
但如果要在Spring Cloud Gateway中使用CircuitBreaker功能,则只能使用其中的2个组件:
- Netfix Hystrix
- Resilience4J
如果使用Spring Cloud CircuitBreaker GatewayFilter Factory,application.yml中可以采用如下方式分别配置:
spring:
cloud:
gateway:
routes:
- id: circuitbreaker_route
uri: lb://backing-service:8088
predicates:
- Path=/consumingServiceEndpoint
filters:
- name: CircuitBreaker
args:
name: myCircuitBreaker
fallbackUri: forward:/inCaseOfFailureUseThis
- RewritePath=/consumingServiceEndpoint, /backingServiceEndpoint
其中,fallbackUri表示熔断后应该访问的地址,可以是外部地址,也可以是内部地址。但以上配置还是过于简单,因为以上配置只是表示对于什么样的请求uri,熔断后采取什么操作,没有说明具体的熔断策略是什么。而具体的熔断策略需要根据具体的断路器组件分别配置。配置的方式是生成CircuitBreakerFactory,这个CircuitBreakerFactory中将包含熔断策略。
由于Spring Cloud Gateway对于resilience4j只支持reactor-resilience4j,所以需要添加依赖:
org.springframework.cloud
spring-cloud-starter-circuitbreaker-reactor-resilience4j
1.0.0.RELEASE
java代码:
@Bean
public ReactiveResilience4JCircuitBreakerFactory defaultCustomizer() {
CircuitBreakerConfig circuitBreakerConfig = CircuitBreakerConfig.custom() //
.slidingWindowType(SlidingWindowType.TIME_BASED) // 滑动窗口的类型为时间窗口
.slidingWindowSize(60) // 时间窗口的大小为60秒
.minimumNumberOfCalls(5) // 在单位时间窗口内最少需要5次调用才能开始进行统计计算
.failureRateThreshold(50) // 在单位时间窗口内调用失败率达到50%后会启动断路器
.enableAutomaticTransitionFromOpenToHalfOpen() // 允许断路器自动由打开状态转换为半开状态
.permittedNumberOfCallsInHalfOpenState(5) // 在半开状态下允许进行正常调用的次数
.waitDurationInOpenState(Duration.ofSeconds(60)) // 断路器打开状态转换为半开状态需要等待60秒
.recordExceptions(Throwable.class) // 所有异常都当作失败来处理
.build();
ReactiveResilience4JCircuitBreakerFactory factory = new ReactiveResilience4JCircuitBreakerFactory();
factory.configureDefault(id -> new Resilience4JConfigBuilder(id)
.timeLimiterConfig(TimeLimiterConfig.custom().timeoutDuration(Duration.ofMillis(500)).build())
.circuitBreakerConfig(circuitBreakerConfig).build());
return factory;
}
其中,Resilience4J CircuitBreaker中有哪些参数,这参数是什么含义,怎么使用,可以查看Resilience4j CircuitBreaker入门指南
配置完成后,Spring Cloud Gateway就会从如下类中加载上述CircuitBreakerFactory
org.springframework.cloud.gateway.config.GatewayResilience4JCircuitBreakerAutoConfiguration
其java代码如下:
/*
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.gateway.config;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.circuitbreaker.resilience4j.ReactiveResilience4JAutoConfiguration;
import org.springframework.cloud.circuitbreaker.resilience4j.ReactiveResilience4JCircuitBreakerFactory;
import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreakerFactory;
import org.springframework.cloud.gateway.filter.factory.FallbackHeadersGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.SpringCloudCircuitBreakerResilience4JFilterFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.DispatcherHandler;
/**
* @author Ryan Baxter
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true)
@AutoConfigureAfter({ ReactiveResilience4JAutoConfiguration.class })
@ConditionalOnClass({ DispatcherHandler.class,
ReactiveResilience4JAutoConfiguration.class, ReactiveCircuitBreakerFactory.class,
ReactiveResilience4JCircuitBreakerFactory.class })
public class GatewayResilience4JCircuitBreakerAutoConfiguration {
@Bean
@ConditionalOnBean(ReactiveResilience4JCircuitBreakerFactory.class)
public SpringCloudCircuitBreakerResilience4JFilterFactory springCloudCircuitBreakerResilience4JFilterFactory(
ReactiveResilience4JCircuitBreakerFactory reactiveCircuitBreakerFactory,
ObjectProvider dispatcherHandler) {
return new SpringCloudCircuitBreakerResilience4JFilterFactory(
reactiveCircuitBreakerFactory, dispatcherHandler);
}
@Bean
@ConditionalOnMissingBean(FallbackHeadersGatewayFilterFactory.class)
public FallbackHeadersGatewayFilterFactory fallbackHeadersGatewayFilterFactory() {
return new FallbackHeadersGatewayFilterFactory();
}
}
Spring Cloud Gateway中需要添加依赖:
org.springframework.cloud
spring-cloud-starter-netflix-hystrix
2.2.1.RELEASE
java代码:
@Bean
public HystrixCircuitBreakerFactory defaultConfig() {
HystrixCircuitBreakerFactory circuitBreakerFactory = new HystrixCircuitBreakerFactory();
circuitBreakerFactory.configureDefault(id -> HystrixCommand.Setter
.withGroupKey(HystrixCommandGroupKey.Factory.asKey(id)).andCommandPropertiesDefaults(
HystrixCommandProperties.Setter().withExecutionTimeoutInMilliseconds(4000)));
return circuitBreakerFactory;
}
配置完成后,Spring Cloud Gateway就会从如下类中加载上述CircuitBreakerFactory
org.springframework.cloud.gateway.config.GatewayHystrixCircuitBreakerAutoConfiguration
其java代码如下:
/*
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.gateway.config;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreakerFactory;
import org.springframework.cloud.gateway.filter.factory.FallbackHeadersGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.SpringCloudCircuitBreakerHystrixFilterFactory;
import org.springframework.cloud.netflix.hystrix.HystrixCircuitBreakerAutoConfiguration;
import org.springframework.cloud.netflix.hystrix.ReactiveHystrixCircuitBreakerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.DispatcherHandler;
/**
* @author Ryan Baxter
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true)
@AutoConfigureAfter({ HystrixCircuitBreakerAutoConfiguration.class })
@ConditionalOnClass({ DispatcherHandler.class,
HystrixCircuitBreakerAutoConfiguration.class, ReactiveCircuitBreakerFactory.class,
ReactiveHystrixCircuitBreakerFactory.class })
public class GatewayHystrixCircuitBreakerAutoConfiguration {
@Bean
@ConditionalOnBean(ReactiveHystrixCircuitBreakerFactory.class)
public SpringCloudCircuitBreakerHystrixFilterFactory springCloudCircuitBreakerHystrixFilterFactory(
ReactiveHystrixCircuitBreakerFactory reactiveCircuitBreakerFactory,
ObjectProvider dispatcherHandler) {
return new SpringCloudCircuitBreakerHystrixFilterFactory(
reactiveCircuitBreakerFactory, dispatcherHandler);
}
@Bean
@ConditionalOnMissingBean(FallbackHeadersGatewayFilterFactory.class)
public FallbackHeadersGatewayFilterFactory fallbackHeadersGatewayFilterFactory() {
return new FallbackHeadersGatewayFilterFactory();
}
}
参考文档
Spring Cloud Gateway
https://cloud.spring.io/spring-cloud-gateway/reference/html
Spring Cloud Circuit Breaker
https://spring.io/projects/spring-cloud-circuitbreaker
Spring Cloud Circuit Breaker With Hystrix
https://cloud.spring.io/spring-cloud-static/spring-cloud-netflix/2.2.1.RELEASE/reference/html/#circuit-breaker-spring-cloud-circuit-breaker-with-hystrix
resilience4j-circuitbreaker
https://resilience4j.readme.io/docs/circuitbreaker
Java:Resilience4j CircuitBreaker入门指南
https://blog.csdn.net/netyeaxi/article/details/104237289