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中将包含熔断策略。

使用resilience4j

由于Spring Cloud Gateway对于resilience4j只支持reactor-resilience4j,所以需要添加依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-circuitbreaker-reactor-resilience4j</artifactId>
    <version>1.0.0.RELEASE</version>
</dependency>

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> dispatcherHandler) {
		return new SpringCloudCircuitBreakerResilience4JFilterFactory(
				reactiveCircuitBreakerFactory, dispatcherHandler);
	}

	@Bean
	@ConditionalOnMissingBean(FallbackHeadersGatewayFilterFactory.class)
	public FallbackHeadersGatewayFilterFactory fallbackHeadersGatewayFilterFactory() {
		return new FallbackHeadersGatewayFilterFactory();
	}

}

使用hystrix

Spring Cloud Gateway中需要添加依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    <version>2.2.1.RELEASE</version>
</dependency>

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> 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

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐