微服务网关Spring Cloud Gateway 之路由定义定位器

举报
qingting-fly 发表于 2021/01/21 18:09:09 2021/01/21
【摘要】 路由定义定位器RouteDefinitionLocator是路由定义定位器的顶级接口,具体的路由定义定位器都继承自该接口,其类图如下。 public interface RouteDefinitionLocator { Flux<RouteDefinition> getRouteDefinitions();}可以看到定义了唯一一个方法,用以获取RouteDefinition。RouteDef...

路由定义定位器

RouteDefinitionLocator是路由定义定位器的顶级接口,具体的路由定义定位器都继承自该接口,其类图如下。 

public interface RouteDefinitionLocator {
 Flux<RouteDefinition> getRouteDefinitions();
}

可以看到定义了唯一一个方法,用以获取RouteDefinitionRouteDefinition对象作为属性定义在GatewayProperties中,而网关的属性是可以直接在网关服务的配置文件中定义。下面我们看一下RouteDefinition中是如何定义路由的。

public class RouteDefinition {
 @NotEmpty
 private String id = UUID.randomUUID().toString();

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

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

 @NotNull
 private URI uri;

 private int order = 0;
}

RouteDefinition中,主要有五个属性:路由id、URI转发地址、order优先级、PredicateDefinition路由断言定义和FilterDefinition过滤器的定义。再深入的话,可以看到断言和过滤器属性是一个Map数据结构,用以存放多个对应的key-value数组。

通过RouteDefinitionLocator的类图,可以看出该接口有四个实现类:

  • 组合方式的CompositeRouteDefinitionLocator
  • 缓存方式的CachingRouteDefinitionLocator
  • 基于属性配置方式的PropertiesRouteDefinitionLocator
  • 基于服务发现的DiscoveryClientRouteDefinitionLocator。

在类图中,看到还有一个接口RouteDefinitionRepository继承自RouteDefinitionLocator,对路由定义进行操作,如保存和删除路由定义。下面我们分别介绍这几种路由定义定位器的实现。

路由定义的数据访问操作

RouteDefinitionRepository接口中的方法用于对RouteDefinition进行增、删、查操作。

public interface RouteDefinitionRepository extends RouteDefinitionLocatorRouteDefinitionWriter {
}
//RouteDefinitionWriter对路由定义进行操作
public interface RouteDefinitionWriter {

 Mono<Void> save(Mono<RouteDefinition> route);

 Mono<Void> delete(Mono<String> routeId);
}

该接口继承了RouteDefinitionWriter,对路由定义进行操作。属于领域驱动设计(DDD)中的仓库,仓库封装了RouteDefinitionLocator操作的方法,领域对象无须和底层数据库交互,它只需要从仓库中获取对象即可,在实现Spring Cloud Gateway内置的API端点时会用到这边的接口。InMemoryRouteDefinitionRepository实现了RouteDefinitionRepository接口,基于内存的路由定义仓库,也是唯一的实现类。当然我们可以根据需要自行扩展,存放在其他存储介质。

public class InMemoryRouteDefinitionRepository implements RouteDefinitionRepository {
 // 定义了一个私有的线程安全的map,用来存储本地的RouteDefinition
 private final Map<String, RouteDefinition> routes = synchronizedMap(new LinkedHashMap<String, RouteDefinition>());
 @Override
 public Mono<Void> save(Mono<RouteDefinition> route) {
  // 保存一个路由定义,将路由定义保存到map中
  return route.flatMap( r -> {
   routes.put(r.getId(), r);
   return Mono.empty();
  });
 }

 @Override
 public Mono<Void> delete(Mono<String> routeId) {
  // 对路由定义操作,删除某个routeId的路由信息
  return routeId.flatMap(id -> {
   if (routes.containsKey(id)) {
    routes.remove(id);
    return Mono.empty();
   }
   return Mono.error(new NotFoundException("RouteDefinition not found: "+routeId));
  });
 }

 @Override
 public Flux<RouteDefinition> getRouteDefinitions() {
  // 获取路由定义,遍历路由定义的map,并返回
  return Flux.fromIterable(routes.values());
 }
}

对路由定义操作的实现比较简单,这里定义了一个私有的线程安全的map,用来存储本地的RouteDefinitionsynchronizedMap是Java集合中提供的静态方法,传入一个Map返回由特殊map支持的同步(线程安全)映射。实际上该方法只是一个工具方法,将传入Map的实现方法加一个同步(synchronized)锁代理,内部还是调用实现的对应方法。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。