示例
SCG配置
1 | json复制代码spring: |
假如我们已经在nacos中注册了一个user-service,user-service有一个接口为/api/hello,当我们请求SCG /user-service/api/hello时就会请求到user-service。
原理
核心类之RouteDefinition的装配
补充了下之前的图
右上角红色的部分为结合注册中心涉及的类。从图中可以看到它们之间的关系,DiscoveryLocatorProperties
与GatewayProperties
类似用于读取discovery相关的配置,通过DiscoveryLocatorPropertis
装配DiscoveryClientRouteDefinitionLocator
,DiscoveryClientRouteDefinitionLocator
是RouteDefinitionLocator
的子类,也是用来存放RouteDefinition
的,最终会同PropertiesRouteDefinitionLocator
一样被组合到CompositeRouteDefinitionLocator
中。
DiscoveryLocatorProperties
和DiscoveryClientRouteDefinitionLocator
是在GatewayDiscoveryClientAutoConfiguration
装配的。
DiscoveryLocatorProperties
DiscoveryRouteDefinition会使用PathRoutePredicateFactory
和RewritePathGatewayFilterFactory
,进行Path匹配和请求Path重写。
1 | json复制代码@ConfigurationProperties("spring.cloud.gateway.discovery.locator") |
GatewayDiscoveryClientAutoConfiguration
1 | json复制代码public static List<PredicateDefinition> initPredicates() { |
结合注册中心其实有两种DiscoveryClient
使用,一种是原始的DiscoveryClient
,一种是ReactiveDiscoveryClient
,不同的注册中心都有相应的实现,如nacos的NacosReactiveDiscoveryClient
。可以通过配置spring.cloud.discovery.reactive.enabled=true
来开启使用Reactive模式的。
1 | json复制代码@Configuration(proxyBeanMethods = false) |
DiscoveryClientRouteDefinitionLocator
DiscoveryClientRouteDefinitionLocator
的主要工作是获取到所有的注册中心上的服务实例,根据服务信息创建PredicateDefnition->FilterDefinition->RouteDefinition。供CompositeRouteDefinitionLocator
获取。
每一个服务都会生成一个RouteDefinition。
1 | json复制代码public class DiscoveryClientRouteDefinitionLocator implements RouteDefinitionLocator { |
请求处理
RewritePathGatewayFilterFactory
上边讲到了当结合注册中心时SCG会为每个路由添加PathRoutePredicateFactory
和RewritePathGatewayFilterFactory
。PathRoutePredicateFactory
用来计算请求是否符合当前路由的条件,RewritePathGatewayFilterFactory
用来重写请求Path,参数regexp=/user-service/(?<remaining>.*),replacement=$(remaining)
,例如请求的Path为/user-service/api/hello,会被重写为/api/hello
。
1 | json复制代码public class RewritePathGatewayFilterFactory |
RouteToRequestUrlFilter
在RewritePathGatewayFilterFactory
重写完请求Path后会执行GlobalFilterRouteToRequestUrlFilter
,该Filter在结合注册中心的情况下,主要是用来将RewritePathGatewayFilterFactory
生成的新的request的scheme修改为路由的lb,例如RewritePathGatewayFilterFactory
生成的请求URI为http://locahost:8080/api/hello
,RouteToRequestUrlFilter
会将其修改为lb://user-service/api/hello
,供lbClicentFilter
使用。
1 | json复制代码@Override |
LoadBalancerClientFilter
到目前为止,还没有获取到真正要调用的服务信息,LoadBalancerClientFilter
就是做这件事的。
1 | json复制代码@Override |
动态路由刷新
事件机制。
在SCG中有RouteRefreshListener
用来监听刷新的事件,比如Nacos使用NacosWatch
来发送HeartbeatEvent。
1 | json复制代码public void nacosServicesWatch() { |
RouteRefreshListener
中监听到HeartbeatEvent
后会发送RefreshRoutesEvent
,CachingRouteLocator
中监听了该事件,而后触发DiscoveryClientRouteDefinitionLocator#getRouteDefinition
从注册中心重新获取一次服务信息,生成RouteDefinition。
本文转载自: 掘金