2.5 双注册双订阅模式
双注册双订阅表示一个Provider应用可以将自身的实例信息注册到多个注册中心上,一个Consumer应用可以订阅到多个注册中心上的服务实例信息。
如图2-18所示,Provider可以把自身的服务实例信息注册到Nacos和Eureka集群上,Consumer发起服务订阅的时候可以从Nacos和Eureka上订阅服务。
图2-18
2.5.1 双注册双订阅模式分析
Spring Cloud自身的编程模型是支持双注册双订阅模式的。
在服务注册侧,我们在2.4.3节分析过Spring Cloud各个注册中心都有AutoServiceRegistration的实现类,比如,NacosAutoServiceRegistration和 EurekaAutoServiceRegistration实现在类内部完成服务的注册。这些AutoServiceRegistration的实现类都实现了 Lifecycle接口,在start过程中完成服务注册操作。
在服务订阅侧,我们在2.4.1节分析过DiscoveryClient 统一了Spring Cloud服务发现的操作。其中,CompositeDiscoveryClient是一个特殊的DiscoveryClient实现:
在 getInstances 方法中,会聚合所有的 DiscoveryClient 实现类找到的服务名,也会遍历每个DiscoveryClient查询服务名对应的实例信息。
下面在一个应用里分别加上 Nacos (com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery)和 Eureka(org.springframework.cloud:spring-cloud-starter-netflix-eureka-client)依赖,用来完成双注册双订阅。
应用启动后,会出现以下报错信息:
从这个报错信息可以很明显地看出,ServiceRegistryAutoConfiguration 自动化配置类的内部类ServiceRegistryEndpointConfiguration内部依赖一个Registration Bean,但是在Nacos和Eureka依赖内部分别会构造 NacosRegistration 和 EurekaRegistration,这样会出现 ServiceRegistry-EndpointConfiguration 并不知道要注入哪个 Registration Bean 的问题。同理,AutoService-RegistrationAutoConfiguration内部的AutoServiceRegistration Bean也会引起一样的问题。
为了解决这个问题,可以在配置文件里过滤这两个自动化配置类:
spring.autoconfigure.exclude=org.springframework.cloud.client.serviceregistry.
ServiceRegistryAutoConfiguration,org.springframework.cloud.client.serviceregistry.
AutoServiceRegistrationAutoConfiguration
加上该配置之后,还需要通过@EnableConfigurationProperties 注解让 AutoServiceRegistration-Properties 配置类生效。这是因为所有的 AutoServiceRegistration 实现类在构造过程中都需要这个配置类Bean。
有了这两个条件之后,即可享受双注册双订阅模式。
2.5.2 案例:使用双注册双订阅模式将Eureka注册中心迁移到Nacos注册中心
假设某公司原先使用 Eureka 作为注册中心,Nacos 开源之后,该公司想把 Eureka替换成Nacos注册中心,要求在这个过程中对客户没有任何影响,也不能造成业务损失。
对于这个场景,可以使用双注册双订阅方案来完成任务。如图2-19所示,这是一个3个阶段的过程图。
第1阶段:Eureka作为注册中心,Provider完成服务注册,Consumer完成服务发现。
第2阶段:双注册双订阅的核心阶段,该阶段内部包括以下4个操作。
·上线新的Provider(拥有双注册能力),这时Eureka 注册中心的Provider有两个实例。
·下线旧的 Provider,下线之后由于新 Provider 也会注册到 Eureka 上,这时旧的Consumer可以找到新Provider的实例。
·上线新的 Consumer(拥有双订阅能力),新 Consumer 可以订阅 Nacos 和 Eureka 集群的服务实例,这时可以订阅到Nacos上的服务实例。
·下线旧的Consumer。
第3阶段:Eureka下线,使用Nacos替换Eureka作为新的注册中心,Provider和Consumer的服务注册和服务发现操作只与Nacos交互。
图2-19
在本节提供的例子中,读者可以配合本书示例使用以下步骤来模拟这个场景:
①启动spring-cloud-netflix-eureka-provider和spring-cloud-netflix-eureka-consumer,模拟一开始使用Eureka作为注册中心的场景。
②启动spring-cloud-eureka-nacos-provider应用,这个应用拥有双注册能力。
③下线spring-cloud-netflix-eureka-provider应用。
④启动spring-cloud-eureka-nacos-consumer应用。
⑤下线spring-cloud-netflix-eureka-consumer应用。