• 全网首发 Spring Cloud Gateway 添加统一前缀思路探讨


    1.前言

    今天学习一下Spring Cloud Gateway,就先再其他博客上逛了逛。遇到有java开发者在某博客问一个问题:Spring Cloud Gateway 如何添加统一的前缀? 当时没有在意,但是脑子里也带着这个问题看起了文档。随着慢慢了解Spring Cloud Gateway 这个问题就有了一点思路。

    2. Gateway工作机制

    这是官方文档上给的Spring Cloud Gateway工作流程图。大意上是客户端请求经过HandlerMapping的处理,如果匹配到路由(Router)就交给网关的web处理程序(Gateway Web Handler)来处理,经过一系列的调用过滤器链(肯定有责任链模式)后转发到被代理的服务执行真正的调用逻辑。

    3. Gateway Handler Mapping

    根据上图,我想找到所谓的Gateway Handler Mapping,看看是何方神圣。我找到了RoutePredicateHandlerMapping,并确定该类就是那个handler Mapping。依赖于Spring Webflux响应式web编程模型。核心方法是getHandlerInternal,通过该方法进行内部处理。

    从代码上看 就是处理了端口关系后,在request放入一些gateway特定的attribute。然后走的一个寻找路由的方法。最后通过Mono.just(webHandler)交给了一个FilteringWebHandler类型的webHandler来处理了。我们先来关注lookupRoute方法,该方法摆明了就是寻找路由。该方法的代码不贴了。就是通过routeLocator.getRoutes()来加载所有的路由并通过断言(Predicate)来进行匹配。匹配到就交给FilteringWebHandler 走过滤器链。在我明白这个流程之后,脑子里那个问题就有了眉目。

    4. FilteringWebHandler

    该handler就是图中的Gateway Web Handler ,包含了一系列的GlobalFilter和GatewayFilter 来组成一个chain来处理前置和后置的逻辑。

    5. 增加统一前缀的思路

    在以前我们知道zuul网关是可以添加一个统一前缀的。但是Spring Cloud Gateway是没有直接提供这个功能的。我已经搞清楚了Gateway的大致工作机制,甚至是一些细节。首先这个统一前缀肯定不能在断言中处理。断言是根据请求的个性化来找目的地路由的,而统一前缀是共性的。放在断言执行后也就是FilteringWebHandler来处理就更不合适了,因为断言执行在Filter之前。但是有一个东西我们没有注意到。Spring Cloud Gateway的机制依赖于Spring Webflux框架的。经过查一些资料RoutePredicateHandlerMapping处理之前是可以设置WebFilter的。因此我找到了一个解决方案:在Gateway Client 和 Gateway Handler Mapping 之间定制一个WebFilter来处理统一前缀。

    6. 思路实现

    机制是这样的,请求带统一前缀请求经过我定制的WebFilter去掉前缀(当然你可以加一些其他你需要的逻辑)然后交给Gateway Handler Mapping处理。代码如下

    经过测试有效。

    7. 总结

    这里其实重点不是如何来实现这个功能,我想传达的是一个解决问题的思路。如何从框架的工作机制出发来分析你所需要解决的问题。找到那个合适的切入点。清晰的思路对于解决问题来说至关重要。其实我现在对Spring Cloud Gateway和Spring Webflux 都并不是很熟练,但是依然找了一个解决问题的方法。不知道你有没有更好的方法呢?相关代码已经上传到码云仓库:https://gitee.com/felord/tino-cloud.git

    关注公众号:码农小胖哥,获取更多资讯

  • 相关阅读:
    多线程学习纪要
    字符编码ASCII、Unicode、UTF-8以及验证
    C# 自定义特性Attribute要点
    Java --- 流操作
    数据库 --- 索引
    Java -- 枚举
    mybatis --- 使用通用mapper或者mybatis-plus进行映射时,当数据库中有大写字母,自定义映射的字段名。
    后端 --- 快速创建一个sb项目 (使用spring官网的https://start.spring.io)
    数据库 --- decimal类型测试
    Java --- 线上故障调优01 打印堆栈信息
  • 原文地址:https://www.cnblogs.com/felordcn/p/12142583.html
Copyright © 2020-2023  润新知