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...