乐趣区

关于nacos:nacos和gateway服务路由缓存刷新

gateway 的服务注册路由默认是第一次启动的时候就加载,有个监听器 RouteRefreshListener 类,外面定义了一些事件,比方 ContextRefreshEvent,HeartbeatEvent 等事件,而后都会调用 ApplicationEventPubilsher.publishEvent(new RereshRoutesEvent(this)); 这里应该就是程序启动时进行的路由刷新操作了。

而后 gateway 有一个刷新的 endpoint,/actuator/gateway/refresh,能够找到这个控制器,外面也调用的 ApplicationEventPubilsher.publishEvent(new RereshRoutesEvent(this)); 办法,这是 spring 的事件驱动,能够看出 gateway 都是通过这个事件来触发服务路由设置的。

顺着找到了监听事件的实现类,CachingRouteLocator,这同时也是 gateway 的缓存路由解决类,这是个包装类(路由配置起源有 yaml 配置,服务注册核心的配置,这里就蕴含了 PropertiesRouteDefinitionLocator,DiscoveryClientRouteDefinitionLocator 类),咱们是应用 nacos 依据服务发现主动配置的,所以咱们关注 DiscoveryClientRouteDefinitionLocator 这个类。

能够看到外面的 getRouteDefinitions() 办法,次要就是 serviceInstances 字段转换成 routeDefinition 的,而这个 serviceInstances 是通过 DiscoveryClient.getServices() 得来的,(这个 DiscoveryClient 和 NacosReactiveDiscoveryClient 能够去看我的对于 spring 和 nacos 服务注册相干的文章)。

这就是 gateway 加载 nacos 注册服务路由的流程。

这里就有个问题了,当 nacos 新注册一个服务的时候,gateway 不晓得,其实 nacos 有定义一个 NacosWatch 的 bean,这个 bean 的会应用 NamingService.subscribe(serviceName, groupName,clusterName,eventListener) 向 nacos 注册一个监听器,NamingEvent(蕴含实例列表等信息)事件,而后向 spring 发送一个 HeartbeatEvent 事件,第一段说了这个事件,触发这个事件是能够刷新路由配置的,然而实际上并不是如此。

因为咱们向 nacos 注册监听器的时候,有个参数是 serviceName,这里默认取的就是以后服务名 spring.application.name,只有当这个服务的实例发生变化时才告诉,如果是一个新的服务,则不告诉(这里我本人写了一个监听器,并监听了一个其余服务的名称,那个服务启动时,这边是会触发的)。

我用的 nacos 版本是 2.x 的,看了网上的一些文章,如同 0.9 版本的能够获取到所有服务的变更事件,难道 nacos 只能启动的时候获取服务列表,前面都不进行动静更新了?目前我还在找这个办法 ….

​​​​​​https://github.com/theonefx/s…

退出移动版