注册中心不一定是Nacos,任何一个实现了SpringCloud 服务发现和注册规范的类库都是可以的
动态路由
动态路由在生产环境是中必不可少的一个环节,但是对应动态路由的资源却比较少,非常典型的是 springcloud——Zuul 动态路由 , 这个是比较典型的一种刷新路由的方式,尤其是在服务比较少时表现良好,当服务数量增高时,刷新路由的时间则会加长,明显不符合我们的要求.
SpringCloud 服务
在 揭秘ribbon配置类为什么不能在主应用程序上下文的@componentscan中 当中曾描述对于每一个注册的服务,zuul都会为它持有有一个 Spring上下文
, 并且每隔 CommonClientConfigKey.ServerListRefreshInterval
毫秒进行一次定时更新, 获取 注册中心
中的服务实例.
既然如此,我只需要定时获取 服务ID
即可, 后续对实例同步完全可以交给定时任务去执行. 定时任务也不必一定要走 Http
的形式去注册中心拿,可以通过 魔改
注册中心共享同一个Memcache/Redis去实现也是可以的. 如此依赖就不需要去轮训所有的 服务ID
来获取实例.
启动详情
- 启动时注册一个
NacosWatch
的定时任务,定时对比本地缓存的服务和注册中心的服务,一旦发生变更则发布心跳事件 NacosWatch
发布心跳事件后,被ZuulRefreshListener
接收,并通过DiscoveryClientRouteLocator
进行路由刷新.DiscoveryClientRouteLocator
会获取所有的服务,并为每一个服务生产一个ZuulRoute
, 当网关收到对应Path
的请求后进行处理- 收到请求后,如果这个服务还没有
Spring上下文
, 则进行Spring上下文的初始化,并启动上边描述的定时任务(定时获取服务实例)
优缺点
- 按照文章的描述来进行操作. 因为一切都是自己操作,可以具备更大的灵活性,并且可以操作
hystrix
的配置信息 - 按照官方来操作则是减少Http调用的较优解,但是原封不动则不能修改
hystrix
的配置ConfigurationManager.getConfigInstance().setProperty("hystrix.command." +
zuulRoute.getServiceId() + ".execution.isolation.thread.timeoutInMilliseconds",
serviceInstance.getMetadata().getOrDefault("timeout", "3000"));
后期肯定还有其他的配置要进行更新,这些也都是需要考虑的