Spring Cloud Gateway 路由功能详解

1. 生成路由的关键步骤

Spring Cloud Gateway 中路由的生成分为两个步骤:

  1. 根据 RouteDefinitonLocator 获取 RouteDefinition
  2. 根据 RouteLocator 获取 Route

其中 RouteDefinitionLocator 有两个实现, PropertiesRouteDefinitionLocator 和 RouteDefinitionRepository , PropertiesRouteDefinitionLocator 对应的是通过配置文件配置路由, RouteDefinitionRepository 对应的是通过仓储方式配置路由,比如 In-Memory 或 Redis 或 MySQL 等等。通过 RouteDefinitionRepository 仓储方式定义的路由我们称之为动态路由,我们可以在不影响现有路由的情况下动态添加路由或更新现有路由。

通过 RouteDefinitonLocator 生成的 RouteDefinition 最终要转换成 Route ,这一步通过 RouteDefinitionRouteLocator 来实现,其主要实现 RouteDefinitionRoute 的转换工作。除此之外,我们还可以通过coding的方式直接定义 RouteLocator ,这需要借助 RouteLocatorBuilder.Builder#build 来实现。

下图是 spring-cloud-gateway 路由相关的核心类图,有没有一目了然的赶脚呢?
在这里插入图片描述

2. 路由配置示例

2.1 通过配置文件配置路由

spring:
  cloud:
    gateway:
      routes:
        - id: addUserCode
          uri: http://localhost:8080/
          filters:
            - AddRequestHeader=userCode, Toman
          predicates:
            - Path=/demo/header

2.2 通过仓储配置路由

如果采用 NoSQL 或关系数据库存储则重写 getRouteDefinitions() 方法即可。

public class InMemoryRouteDefinitionRepository implements RouteDefinitionRepository {

	private final Map<String, RouteDefinition> routes = synchronizedMap(
			new LinkedHashMap<String, RouteDefinition>());

	@Override
	public Mono<Void> save(Mono<RouteDefinition> route) {
		return route.flatMap(r -> {
			routes.put(r.getId(), r);
			return Mono.empty();
		});
	}

	@Override
	public Mono<Void> delete(Mono<String> routeId) {
		return routeId.flatMap(id -> {
			if (routes.containsKey(id)) {
				routes.remove(id);
				return Mono.empty();
			}
			return Mono.defer(() -> Mono.error(
					new NotFoundException("RouteDefinition not found: " + routeId)));
		});
	}

	@Override
	public Flux<RouteDefinition> getRouteDefinitions() {
		return Flux.fromIterable(routes.values());
	}

}

2.3 通过 RouteLocatorBuilder 创建 RouteLocator

@Bean
RouteLocator requestHeader(RouteLocatorBuilder builder) {
    return builder.routes().route(
            predicateSpec -> predicateSpec.path("/demo/header")
                    .filters(filterSpec -> filterSpec.addRequestHeader("userCode", "Toman"))
                    .uri("http://localhost:8080").order(-1)
    ).build();
}

3. 路由的缓存处理

Spring Cloud Gateway获取路由的入口是 CachingRoteLocator.getRoutes() 。CahingRouteLocator负责路由的缓存工作,缓存是通过将路由信息存储到了本地map来实现的。

缓存信息的获取交由 CachingRouteLocatordelegator 来实现,delegatorCompositeRouteLocator ,它采用组合模式将所有的RouteLocator 实现组合到 delegators 内。

真正的 RouteLocator 实现有 RouteDefinitionRouteLocator 和通过 RouteLocatorBuilder#build 创建的 RouteLocator 对象。
在这里插入图片描述

4. 路由的刷新

通过动态路由更新路由配置信息后,通过spring事件机制发送 RefreshRoutesEvent 事件。 CachingRouteLocator 会监听该事件,在收到 RefreshRoutesEvent 事件后, 会清空缓存信息,待下次请求时重新加载路由信息并缓存。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值