Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spring Cloud 教程 - Spring Cloud Gateway动态路由实现 #11

Open
TFdream opened this issue Jul 17, 2020 · 0 comments
Open

Spring Cloud 教程 - Spring Cloud Gateway动态路由实现 #11

TFdream opened this issue Jul 17, 2020 · 0 comments

Comments

@TFdream
Copy link
Owner

TFdream commented Jul 17, 2020

Spring Cloud Gateway配置路由主要有两种方式:一种是用yml配置文件,一种是写代码里,这两种方式都是不支持动态配置的。

现实生产环境中,使用Spring Cloud Gateway都是作为所有流量的入口,为了保证系统的高可用,尽量避免系统的重启,所以需要Spring Cloud Gateway的动态路由来处理。

首先我们来看看gateway是如何加载这些配置信息的。

注:本篇 Spring Boot版本为 2.3.0.RELEASE,Spring Cloud版本为Hoxton.SR5,spring-cloud-gateway版本为2.2.3.RELEASE。

1、路由初始化

无论是yml还是代码配置,这些配置最终都是被封装到RouteDefinition对象中,如下:

package org.springframework.cloud.gateway.route;

/**
 * @author Spencer Gibb
 */
@Validated
public class RouteDefinition {

	private String id;

	@NotEmpty
	@Valid
	private List<PredicateDefinition> predicates = new ArrayList<>();

	@Valid
	private List<FilterDefinition> filters = new ArrayList<>();

	@NotNull
	private URI uri;

	private Map<String, Object> metadata = new HashMap<>();

	private int order = 0;

	public RouteDefinition() {
	}

一个RouteDefinition有个唯一的ID,如果不指定,就默认是UUID,多个RouteDefinition组成了gateway的路由系统。

所有路由信息在系统启动时就被加载装配好了,并存到了内存里,这点我们从 org.springframework.cloud.gateway.config.GatewayAutoConfiguration 类可以看出,如下:

/**
 * @author Spencer Gibb
 * @author Ziemowit Stolarczyk
 */
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true)
@EnableConfigurationProperties
@AutoConfigureBefore({ HttpHandlerAutoConfiguration.class,
		WebFluxAutoConfiguration.class })
@AutoConfigureAfter({ GatewayLoadBalancerClientAutoConfiguration.class,
		GatewayClassPathWarningAutoConfiguration.class })
@ConditionalOnClass(DispatcherHandler.class)
public class GatewayAutoConfiguration {

	@Bean
	public StringToZonedDateTimeConverter stringToZonedDateTimeConverter() {
		return new StringToZonedDateTimeConverter();
	}

	@Bean
	public RouteLocatorBuilder routeLocatorBuilder(
			ConfigurableApplicationContext context) {
		return new RouteLocatorBuilder(context);
	}

	//yml文件中配置的路由信息
	@Bean
	@ConditionalOnMissingBean
	public PropertiesRouteDefinitionLocator propertiesRouteDefinitionLocator(
			GatewayProperties properties) {
		return new PropertiesRouteDefinitionLocator(properties);
	}

	@Bean
	@ConditionalOnMissingBean(RouteDefinitionRepository.class)
	public InMemoryRouteDefinitionRepository inMemoryRouteDefinitionRepository() {
		return new InMemoryRouteDefinitionRepository();
	}

	@Bean
	@Primary
	public RouteDefinitionLocator routeDefinitionLocator(
			List<RouteDefinitionLocator> routeDefinitionLocators) {
		return new CompositeRouteDefinitionLocator(
				Flux.fromIterable(routeDefinitionLocators));
	}

	@Bean
	@Primary
	@ConditionalOnMissingBean(name = "cachedCompositeRouteLocator")
	// TODO: property to disable composite?
	public RouteLocator cachedCompositeRouteLocator(List<RouteLocator> routeLocators) {
		return new CachingRouteLocator(
				new CompositeRouteLocator(Flux.fromIterable(routeLocators)));
	}

	@Bean
	public RouteRefreshListener routeRefreshListener(
			ApplicationEventPublisher publisher) {
		return new RouteRefreshListener(publisher);
	}
}

PropertiesRouteDefinitionLocator 就是 我们在yml文件中装配的路由信息,该类继承了RouteDefinitionLocator,RouteDefinitionLocator就是路由的装载器,里面只有一个方法,就是获取路由信息的。

RouteDefinitionLocator接口有多个实现类,分别对应不同方式配置的路由方式,
image

比较关键的几个如下:

  • CachingRouteDefinitionLocator:为RouteDefinitionLocator类提供缓存功能;
  • CompositeRouteDefinitionLocator:组合多种RouteDefinitionLocator实现;
  • PropertiesRouteDefinitionLocator:从配置文件(例如 YML / properties 等)读取RouteDefinition;
  • DiscoveryClientRouteDefinitionLocator:从注册中心(例如 Eureka、Consul、Nacos、Zookeeper等)读取RouteDefinition;

通过这几个实现类,再结合上面的AutoConfiguration里面的Primary信息,就知道加载配置信息的顺序。

PropertiesRouteDefinitionLocator-->|配置文件加载初始化| CompositeRouteDefinitionLocator
RouteDefinitionRepository-->|存储器中加载初始化| CompositeRouteDefinitionLocator
DiscoveryClientRouteDefinitionLocator-->|注册中心加载初始化| CompositeRouteDefinitionLocator

相关资料

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant