深入解析微服务网关Spring Cloud Gateway 之 API 接口详解

举报
qingting-fly 发表于 2021/01/12 08:59:52 2021/01/12
【摘要】 ❝系新的组件解析系列文章《微服务网关 Spring Cloud Gageway解析》的介绍与深入讲解。欢迎关注、转发、评论。❞在前面的一篇文章,我们介绍了 Spring Cloud 的API 端点概览。网关一共提供了7个内置端点。分别为:/actuator/gateway/routes/{id},methods=[DELETE],删除单个路由/actuator/gateway/routes/...

系新的组件解析系列文章《微服务网关 Spring Cloud Gageway解析》的介绍与深入讲解。欢迎关注、转发、评论。

在前面的一篇文章,我们介绍了 Spring Cloud 的API 端点概览。网关一共提供了7个内置端点。分别为:

  • /actuator/gateway/routes/{id},methods=[DELETE],删除单个路由
  • /actuator/gateway/routes/{id},methods=[POST],增加单个路由
  • /actuator/gateway/routes/{id},methods=[GET],查看单个路由
  • /actuator/gateway/routes],methods=[GET],获取路由列表
  • /actuator/gateway/refresh,methods=[POST],路由刷新
  • /actuator/gateway/globalfilters,methods=[GET],获取全局过滤器列表
  • /actuator/gateway/routefilters,methods=[GET],路由过滤器工厂列表
  • /actuator/gateway/routes/{id}/combinedfilters,methods=[GET],获取单个路由的联合过滤器

Spring Cloud Gateway的内置端点纳管到Spring Boot-Actuator中,@RestControllerEndpoint是定义在Actuator中的注解,将类型标识为仅通过Spring MVC或者Spring WebFlux公开的REST端点。id的值为gateway也会加入到暴露的接口中作为前缀。 GatewayControllerEndpoint的构造函数如上,该类的实例化是在GatewayAutoConfiguration中进行的,构造参数有5个:

  • routeDefinitionLocator,路由定义定位器
  • globalFilters,全局过滤器
  • GatewayFilters,网关过滤器工厂
  • routeDefinitionWriter,存储器 RouteDefinitionLocator 对象
  • routeLocator,路由定位器

下面将会分别介绍这些内置的端点。

路由操作端点

  • 单个路由操作
 @DeleteMapping("/routes/{id}")
 public Mono<ResponseEntity<Object>> delete(@PathVariable String id) {
  return this.routeDefinitionWriter.delete(Mono.just(id))
    .then(Mono.defer(() -> Mono.just(ResponseEntity.ok().build())))
    .onErrorResume(t -> t instanceof NotFoundException, t -> Mono.just(ResponseEntity.notFound().build()));
 }

如上为删除单个路由,实现比较简单,RouteDefinitionWriter中定义的删除方法调用即可,并将相应结果返回给客户端。增加单个路由和查看单个路由实现类似,不在赘述。

  • 路由列表
 @GetMapping("/routes")
 public Mono<Map<String, List>> routes() {
  Mono<List<RouteDefinition>> routeDefs = this.routeDefinitionLocator.getRouteDefinitions().collectList();
  Mono<List<Route>> routes = this.routeLocator.getRoutes().collectList();
  return Mono.zip(routeDefs, routes).map(tuple -> {
   Map<String, List> allRoutes = new HashMap<>();
   allRoutes.put("routeDefinitions", tuple.getT1());
   allRoutes.put("routes", tuple.getT2());
   return allRoutes;
  });
 }

分别获取路由定义与路由列表,zip函数将这两个列表合并成一个新的Mono,并将routeDefinitions和routes存到map中。返回的结果如下示例:

{
    "routes": [
        {
            "id""4bee1ec4-b72c-43a4-86e2-e65bc31184a7",
            "uri""http://httpbin.org:80",
            "order": -1,
            "predicate": {},
            "filters": [
                {
                    "order": 0
                }
            ]
        }
    ],
    "routeDefinitions": [
        {
            "id""websocket_test",
            "predicates": [
                {
                    "name""Path",
                    "args": {
                        "_genkey_0""/echo"
                    }
                }
            ],
            "filters": [],
            "uri""ws://localhost:9000",
            "order": 9000
        }
    ]
}

过滤器端点

获取过滤器有三个端点:全局过滤器列表、过滤器工厂列表和单个路由的联合过滤器。实现的方法都差不多,这边列一下获取单个路由的混合过滤器列表的实现。

 @GetMapping("/routes/{id}/combinedfilters")
 public Mono<HashMap<String, Object>> combinedfilters(@PathVariable String id) {
  //获取单个路由的过滤器,包括全局和路由配置的过滤器(暂时没有实现全局过滤器获取)
  return this.routeLocator.getRoutes()
    .filter(route -> route.getId().equals(id))
    .reduce(new HashMap<>(), this::putItem);
 }

我们可以看到,目前返回的过滤器不包括 GlobalFilter ,可以调用 /globalfilters 查看。等待未来的版本支持。

路由刷新

路由缓存刷新的实现如下:

 @PostMapping("/refresh")
 public Mono<Void> refresh() {
     this.publisher.publishEvent(new RefreshRoutesEvent(this));
  return Mono.empty();
 }

其实就是发布一个更新路由的事件,然后监听器触发缓存路由的更新。CachingRouteLocator中实现了相关的刷新操作。

小结

至此,关于Spring Cloud Gateway 的源码分析已经完成,后续的文章将会介绍Spring Cloud Gateway的进阶应用。


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

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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