前言
我们这里 大致梳理一下 spring-cloud-gateway 路由的相关处理
spring-cloud 微服务组件中的网关
这里主要分为几个 步骤
- 路由规则怎么获取
- 如何路由
- 网关过滤器的处理
- 如何转发请求道下游微服务组件
路由规则怎么获取 ?
GatewayAutoConfiguration 中包含了 spring-cloud-gateway 实现所需要的各个对象
CachingRouteLocator 存储的是路由相关信息, CachingRouteLocator - CompositeRouteLocator - RouteDefinitionRouteLocator - CompositeRouteDefinitionLocator - DiscoveryClientRouteDefinitionLocator/PropertiesRouteDefinitionLocator
路由上面最基层的 CompositeRouteDefinitionLocator 来自于 routeDefinitionLocator, 各个 List<RouteDefinitionLocator> 来自于 spring 容器,
DiscoveryClientRouteDefinitionLocator 来自于 GatewayDiscoveryClientAutoConfiguration, 这里面定义的路由是一套默认路由, /appName/** -> appName
PropertiesRouteDefinitionLocator 来自于 GatewayAutoConfiguration
这里面定义的路由是从 properties 中加载路由配置
我们这里主要关心 DiscoveryClientRouteDefinitionLocator 和 PropertiesRouteDefinitionLocator, 这两套路由规则 加起来就是完整的路由规则
这里面根据注册的服务 为每一个服务注册了一套默认的路由方式
这一套默认的配置方式也请参见 GatewayDiscoveryClientAutoConfiguration 中的 DiscoveryLocatorProperties

PropertiesRouteDefinitionLocator
这里的配置来自于 GatewayApplication 读取到的路由配置信息, 转换为 RouteDefinition 列表

路由规则的使用
如下是某一个具体的 Predicate 的使用的地方

FluxIterable$IterableSubscription.slowPath 中迭代所有的 路由配置
MonoFilterWhen$MonoFilterWhenMain.onNext 目前是调用 apply 方法, 后面处理 GatewayFilter 会调用 p.subscribe(inner)
迭代的路由列表来自于

FluxIterable 的路由列表来自于 外层 CacheFlux
这里的 cacheMap 来自于 CachingRouteLocator 的路由缓存 cache

CacheFlux 来自于 CachingRouteLocator 中创建, routes 为当前 RouteLocator 维护的路由列表, 带缓存
这里拿到的路由列表即为 DiscoveryClientRouteDefinitionLocator + PropertiesRouteDefinitionLocator + 自定义的 RouteDefinicationLocator 获取到的路由列表

路由规则的自动刷新
默认的这套配置中 路由规则会自动刷新
收到 心跳信息之后, RouteRefreshListener 会发出一个 RefreshRoutesEvent
然后 CachingRouteLocator 中会刷新路由缓存


Gateway Filter 的使用
比如 StripPrefix 对应会创建 RewritePathGatewayFilter
然后其中的业务处理就是 去掉 系统名称, /ay-resource-portals, 处理如下

各个 GatewayFilter 的处理是基于 责任链模式, 这已经是一个 很典型的责任链的使用场景
比如 tomcat 的 Filter 等等

转发 请求到下游组件
这里具体转发 请求到下游的组件 也是基于 GatewayFilter, 主要是基于 NettyRoutingFilter
基于 netty 封装的 httpClient 来发送 http 请求, 下游的服务信息来自于 匹配的 路由信息

如下是对于响应的处理
后面会响应给客户端

将数据响应给客户端
这里将 响应体 返回给客户端

完