SpringCloud 基于Nacos和Eureka 实现双注册双订阅

一、使用场景/原因

  • 过渡期迁移:

    • 当系统从一个服务注册中心迁移到另一个时,例如从 Eureka 迁移到 Nacos,可以在过渡期内同时使用两个注册中心,确保服务平稳迁移,逐步过渡,避免一次性切换带来的风险。
  • 兼容性考虑:

    • 不同的微服务可能使用不同的注册中心,为了兼容这些微服务,可以同时支持 Nacos 和 Eureka。这样既可以支持新开发的服务使用 Nacos,也可以兼容旧有的使用 Eureka 的服务。

二、增加注册中心

        本篇文章我们升级的项目本身现在使用的是Eureka,然后新创建的项目采用的是 Nacos来作为注册中心,这就会出现一个问题 , 那就是微服务之间调用困难, 因为新旧微服务分别都注册在不同的注册中心。如果采用一次性整体切换成Nacos,对于已经运行了很久的现有项目来说, 工作量有点大, 所以我们采用这种办法, 就是项目同时支持Nacos、Eureka两个服务注册,为后续的逐步迁移做准备。

 2.1、Pom文件分别配置Nacos、Eureka

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

2.2、启动类注解

1、注释掉 @EnableEurekaClent   // 弃用Eureka 专门的注册注解

2、新添加 @EnableDiscoveryClient  

@SpringBootApplication
//@EnableEurekaClient
@EnableDiscoveryClient
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

2.3、项目配置文件Application.yml

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:9002/eureka/
  instance:
    prefer-ip-address: true
server:
  port: 11500
spring:
  application:
    name: Ko
  cloud:
    service-registry:
      auto-registration:
        enabled: false
    nacos:
      discovery:
        server-addr: http://127.0.0.1:9999
        namespace: 47dea8bf-3dce-4c86-82bc-82f1497c57d2

三、启动项目

至此,并没有结束,配置结束后,我们来启动项目,看效果。

不出意外的话,会出现下面这个报错, 出意外的话那就是出意外了 🙃🙃🙃🙃

 3.1、自动注册时候报错

图和文字是一样的 为了方便看,可方便复制

Disconnected from the target VM, address: 'localhost:63051', transport: 'socket'
***************************
APPLICATION FAILED TO START
***************************

Description:

Field autoServiceRegistration in org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration required a single bean, but 2 were found:
	- nacosAutoServiceRegistration: defined by method 'nacosAutoServiceRegistration' in class path resource [com/alibaba/cloud/nacos/registry/NacosServiceRegistryAutoConfiguration.class]
	- eurekaAutoServiceRegistration: defined by method 'eurekaAutoServiceRegistration' in class path resource [org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration.class]


Action:

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed

        言简意赅的阐述一下出现这个报错的原因是因为, @EnableDiscoveryClient 在启动的时候会进行自动注册, 干这件事情的就是 AutoServiceRegistrationAutoConfiguration ,然后这个了类在一开始 注入了一个类型为 AutoServiceRegistration的类 

继续往下看, AutoServiceRegistration这个类的实现有两个,分别是EurekaAutoServiceRegistration 和 NacosAutoServiceRegistration,这都是因为引入了两个注册中心后导致的,

然后我们再说日志中给出的建议,他是说建议你在其中一个类上面加@Primary , 这样虽然能解决问题, 但是,这是源代码,无法修改的,难道不修改源码就没什么办法了么 ?

  

让我们在回到最开始的那个自动配置类上 , 注意看 , 这个类的init , 在进行了注入之后,  什么都没有做 , 就只是做了一下Check ,我个人感觉啊, 把这个自动配置类, 给忽略掉,也就是将其排除。 不让他自动执行!

3.2、注入失败问题解决

前面我们说到,为了解决在自动注册时候注入类时候出现两个配置类的问题, 我们采用排除这个配置类的方式,排除办法有两种, 可以根据习惯自行选择

3.2.1 application.yml 配置方式 autoconfigure.exclude

spring:
  application:
    name: Ko
  cloud:
    nacos:
      discovery:
        server-addr: http://127.0.0.1:9999
        namespace: 47dea8bf-3dce-4c86-82bc-82f1497c57d2
      config:
        enabled: false
        server-addr: http://127.0.0.1:9999
        import-check: false
        namespace: 47dea8bf-3dce-4c86-82bc-82f1497c57d2
  autoconfigure:
    exclude: org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration

3.2.2 Application 启动类配置方式

// exclude 同样可以起到忽略的作用 ,至于这里为什么要忽略两个,继续往下看,会说到
@SpringBootApplication(exclude = {AutoServiceRegistrationAutoConfiguration.class,ServiceRegistryAutoConfiguration.class})
@EnableDiscoveryClient
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

然后我们再重启项目,提示的错误还有一个地方的注册配置类,遇到了同样的问题,(请注意,下面这个报错,如果你并没有使用  spring-boot-starter-actuator 这个组件就不会有这个问题)如下:

***************************
APPLICATION FAILED TO START
***************************

Description:

Field registration in org.springframework.cloud.client.serviceregistry.ServiceRegistryAutoConfiguration$ServiceRegistryEndpointConfiguration required a single bean, but 2 were found:
	- nacosRegistration: defined by method 'nacosRegistration' in class path resource [com/alibaba/cloud/nacos/registry/NacosServiceRegistryAutoConfiguration.class]
	- eurekaRegistration: defined in BeanDefinition defined in class path resource [org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration$RefreshableEurekaClientConfiguration.class]


Action:

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed
 ******** 
Disconnected from the target VM, address: 'localhost:63833', transport: 'socket'

这次提示的配置类是 ServiceRegistryAutoConfiguration  , 按照老办法,直接忽略这个配置类, 但这个类不像上一个那样实际什么都没做,这个还是做了点事情的 , 这个类加载的目的是因为我们项目中使用到的 Spring的监控组件, 存在这个依赖时,即使执行了上文的操作,启动时还是报错。就是因为在启动之初这个监控组件会将Service注册,便于后续的监控,所以我们可以将这个也选择直接排除这个配置类, 至于影响嘛,无非就是监控组件中会少一个EndPoint,无伤大雅。

/**
 * @author Spencer Gibb
 */
@Configuration(proxyBeanMethods = false)
public class ServiceRegistryAutoConfiguration {

	@ConditionalOnBean(ServiceRegistry.class)
	@ConditionalOnClass(Endpoint.class)
	protected class ServiceRegistryEndpointConfiguration {

		@Autowired(required = false)
		private Registration registration;

		@Bean
		@ConditionalOnEnabledEndpoint
		public ServiceRegistryEndpoint serviceRegistryEndpoint(
				ServiceRegistry serviceRegistry) {
			ServiceRegistryEndpoint endpoint = new ServiceRegistryEndpoint(
					serviceRegistry);
			endpoint.setRegistration(this.registration);
			return endpoint;
		}

	}

}

至此,分别排除了AutoServiceRegistrationAutoConfiguration 和 ServiceRegistryAutoConfiguration 这两个自动配置类后,项目便可以正常启动,且会注册到两个注册中心

但是请注意,这种行为并不是长久之道,只适合在项目架构升级过渡期使用,或者其他特殊场景下使用,日常使用中还是建议 使用同一种注册中心,

  • 10
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值