注册中心不一定是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 的配置
    1. ConfigurationManager.getConfigInstance().setProperty("hystrix.command." +
    2. zuulRoute.getServiceId() + ".execution.isolation.thread.timeoutInMilliseconds",
    3. serviceInstance.getMetadata().getOrDefault("timeout", "3000"));

    后期肯定还有其他的配置要进行更新,这些也都是需要考虑的