SpringBoot通过配置切换注册中心(多注册中心nacos和eureka)
场景:
因项目需要,一个springcloud微服务工程需要同时部署到A,B两个项目使用,但A项目使用Eureka注册中心,B项目使用Nacos注册中心,现在需要通过部署时修改配置来实现多注册中心的切换。
解决思路:
如果同时引入nacos和eureka的依赖和配置,不做任何处理,会导致启动失败:
***************************
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
不难看出失败原因是单例bean找到了两个实例,那么该如何解决这个问题呢?首先想到的肯定是删除掉暂时不需要使用的实例(如使用eureka注册中心则删掉引入pom的nacos依赖),这样做是没有问题的,但是维护成本比较高。能不能从springboot自动装配原理入手,找到更便捷的方法呢?接着看:
我们都知道SpringBoot的启动类的@SpringBootApplication是一个组合注解,它里面的@EnableAutoConfiguration会引入AutoConfigurationImportSelector.class


从这个类的方法getAutoConfigurationEntry()一层一层点进去看,
SpringFactoriesLoader.loadFactories()会去检索META-INF/spring.factories文件。
protected List<AutoConfigurationImportFilter> getAutoConfigurationImportFilters() {return SpringFactoriesLoader.loadFactories(AutoConfigurationImportFilter.class, this.beanClassLoader);}
那么思路就比较清晰了,我们可以通过实现AutoConfigurationImportFilter接口,将自己的过滤逻辑写在实现类中,就可以实现自定义的自动装配过滤器了。
上代码:
通过把1、2、3的代码放到一个starter中,然后在具体的项目中引用这个starter,配置文件中添加4的配置就可以切换了,当然具体nacos和eureka在yml中的配置还是分开写,只需指定用那个配置就行
1.过滤器
package com.demo.business;import com.demo.business.constants.RegistrationCenterConstants;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.AutoConfigurationImportFilter;
import org.springframework.boot.autoconfigure.AutoConfigurationMetadata;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;public class EngineAutoConfigurationImportFilter implements AutoConfigurationImportFilter, EnvironmentAware {private Environment environment;@Overridepublic boolean[] match(String[] autoConfigurationClasses, AutoConfigurationMetadata autoConfigurationMetadata) {//获取配置的注册中心,默认为nacosString registryType = environment.getProperty("registry.type", RegistrationCenterConstants.NACOS);boolean[] match = new boolean[autoConfigurationClasses.length];//当自定义标识为eureka,则排除nacos的自动装配,反之同理;if (registryType.equals(RegistrationCenterConstants.EUREKA)) {for (int i = 0; i < autoConfigurationClasses.length; i++) {match[i] = !StringUtils.isNotBlank(autoConfigurationClasses[i]) ||!autoConfigurationClasses[i].equals(RegistrationCenterConstants.NACOS_SERVICE_REGISTRY_AUTO_CONFIGURATION);}} else {for (int i = 0; i < autoConfigurationClasses.length; i++) {if (StringUtils.isNotBlank(autoConfigurationClasses[i])){match[i] = !RegistrationCenterConstants.EUREKA_DISCOVERY_CLIENT_CONFIGURATION.equals(autoConfigurationClasses[i])&& !RegistrationCenterConstants.EUREKA_AUTO_CONFIGURATION_CLASSES.equals(autoConfigurationClasses[i]);}}}return match;}@Overridepublic void setEnvironment(Environment environment) {this.environment = environment;}
}或者以下这样也可以
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.AutoConfigurationImportFilter;
import org.springframework.boot.autoconfigure.AutoConfigurationMetadata;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;public class EngineAutoConfigurationImportFilter implements AutoConfigurationImportFilter, EnvironmentAware {private Environment environment;public EngineAutoConfigurationImportFilter() {}public boolean[] match(String[] autoConfigurationClasses, AutoConfigurationMetadata autoConfigurationMetadata) {String registryType = this.environment.getProperty("registry.type", "eureka");boolean[] match = new boolean[autoConfigurationClasses.length];//提取成常量String prefix = registryType.equals("nacos") ? "org.springframework.cloud.netflix.eureka" : "com.alibaba.cloud.nacos";for(int i = 0; i < autoConfigurationClasses.length; ++i) {if (StringUtils.isNotBlank(autoConfigurationClasses[i])) {match[i] = !autoConfigurationClasses[i].startsWith(prefix);}}return match;}public void setEnvironment(Environment environment) {this.environment = environment;}
}
2.常量类
package com.demo.business.constants;/*** 注册中心相关常量类*/
public class RegistrationCenterConstants {public static final String NACOS = "nacos";public static final String EUREKA = "eureka";public static final String EUREKA_AUTO_CONFIGURATION_CLASSES = "org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration";public static final String EUREKA_DISCOVERY_CLIENT_CONFIGURATION = "org.springframework.cloud.netflix.eureka.EurekaDiscoveryClientConfiguration";public static final String NACOS_SERVICE_REGISTRY_AUTO_CONFIGURATION = "com.alibaba.cloud.nacos.registry.NacosServiceRegistryAutoConfiguration";或者
public static final String NACOS_PREFIX = "com.alibaba.cloud.nacos";public static final String EUREKA_PREFIX = "org.springframework.cloud.netflix.eureka";}
3.spring.factories文件(注意路径一定要在META-INF包下)
org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\com.example.demo.business.EngineAutoConfigurationImportFilter
4.配置文件添加
registry:type: nacos
效果
通过修改配置项registry.type就可以实现eureka和nacos的切换了
相关文章:
SpringBoot通过配置切换注册中心(多注册中心nacos和eureka)
场景: 因项目需要,一个springcloud微服务工程需要同时部署到A,B两个项目使用,但A项目使用Eureka注册中心,B项目使用Nacos注册中心,现在需要通过部署时修改配置来实现多注册中心的切换。 解决思路: 如果同时…...
自动驾驶学习笔记(三)——场景设计
#Apollo开发者# 学习课程的传送门如下,当您也准备学习自动驾驶时,可以和我一同前往: 《自动驾驶新人之旅》免费课程—> 传送门 《2023星火培训【感知专项营】》免费课程—>传送门 文章目录 前言 场景设计平台 场景地图 场景基本…...
第 115 场 LeetCode 双周赛题解
A 上一个遍历的整数 模拟 class Solution { public:vector<int> lastVisitedIntegers(vector<string> &words) {vector<int> res;vector<int> li;for (int i 0, n words.size(); i < n;) {if (words[i] ! "prev")li.push_back(stoi…...
【IDE插件教学】华为云应用中间件系列—Redis实现(电商游戏应用)排行榜示例
云服务、API、SDK,调试,查看,我都行 阅读短文您可以学习到:应用中间件系列之Redis实现(电商游戏应用)排行榜示例 1 什么是DEVKIT 华为云开发者插件(Huawei Cloud Toolkit)&a…...
Linux:mongodb数据库源码包安装(4.4.25版本)
环境 系统:centos7 本机ip:192.168.254.1 准备的mongodb包 版本 : 4.4.25 全名称:mongodb-linux-x86_64-rhel70-4.4.25.tgz 下载源码包 Download MongoDB Community Server | MongoDBhttps://www.mongodb.com/try/downloa…...
pdf怎么合并在一起?
pdf怎么合并在一起?对于pdf合并这个问题,有的小伙伴想很简单,只需要将文件直接复制再其中的一个后面不就完事了吗。其实不然,因为我们如果要是需要将很多文件进行合并的话,就会产生很多问题的。总之,在现在…...
杀死僵尸进程ZooKeeperMain
关闭Hadoop后jps发现还有个进程ZooKeeperMain没有关闭,使用kill -9 <>也没有用,这种就是僵尸进程,需要用父进程ID来杀死 解决方法 话不多说,直接上解决方案, 1. 第一步 清楚需要关闭的进程ID,我…...
JavaScript class和function的区别
待整理: 一 二 Class 组件和 Function 组件是 React 中创建组件的两种主要方式。他们在语法和功能上有一些不同。以下分点是 Class 组件和 Function 组件在不同方面的对比: 1. 语法结构 Class 组件: import React, { Component } from …...
MySQL8.0修改mysql允许远程连接
1、连接服务器: mysql -u root -p2、看当前所有数据库:show databases; 3、进入mysql数据库:use mysql; 4、查看mysql数据库中所有的表:show tables; 5、查看user表中的数据:select Host, User,Password from user; 6、修改us…...
【算法训练-排序算法 二】【手撕排序】快速排序、堆排序、归并排序
废话不多说,喊一句号子鼓励自己:程序员永不失业,程序员走向架构!本篇Blog的主题是【手撕排序系列】,使用【数组】这个基本的数据结构来实现,这个高频题的站点是:CodeTop,筛选条件为&…...
C# RestoreFormer 图像修复
效果 项目 代码 using Microsoft.ML.OnnxRuntime; using Microsoft.ML.OnnxRuntime.Tensors; using OpenCvSharp; using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.Windows.Forms;namespace 图像修复 {pu…...
yolov5+车辆重识别【附代码】
本篇文章主要是实现的yolov5和reid结合的车辆重识别项目。是在我之前实现的yolov5_reid行人重识别的代码上修改实现的baseline模型。 目录 相关参考资料 数据集说明 环境说明 项目使用说明 vehicle reid训练 yolov5车辆重识别 从视频中获取想要检测的车(待检测车辆) 车…...
C语言练习百题之#ifdef和#ifndef的应用
#if, #ifdef, 和 #ifndef 是C语言预处理指令,它们可以用于条件编译,帮助控制程序的编译过程。以下是各种应用场景以及一些注意事项: 1. 使用 #ifdef 和 #ifndef 检查宏是否定义: 应用场景: 检查宏是否已经在代码中定义…...
与C语言不同的基础语法
一、不同 1.可同时定义并初始化多个变量 2.有string字符串类型 3.可在循环中定义变量 #include<iostream> using namespace std; int main() {int a1,b2;//可同时定义并初始化多个变量string name;//字符串类型 char array[3]; for(int i1;i<3;i)//for中定义i变量…...
Python文件读写实战:处理日常任务的终极工具!
更多资料获取 📚 个人网站:涛哥聊Python Python文件的读写操作时,有很多需要考虑的细节,这包括文件打开方式、读取和写入数据的方法、异常处理等。 在本文中,将深入探讨Python中的文件操作,旨在提供全面的…...
思维模型 秩序
本系列文章 主要是 分享 思维模型,涉及各个领域,重在提升认知。秩序是事物正常运行的基石。有序的安排是成功的先决条件。 1 秩序的应用 1.1 秩序在不同科学领域中的应用 物理学和天文学: 物理学家通过研究原子和分子的有序排列来理解物质的…...
pyqt5移动鼠标时显示鼠标坐标
问题: 只有按住鼠标左键或者右键移动的时候才会获取坐标值,即使对QLabel控件使用setMouseTracking(True)也无法解决。 解决方法: 在初始化构造函数中加入 self.setMouseTracking(True) self.centralwidget.setMouseTracking(True) 并且对…...
分享一下开发回收废品小程序的步骤
随着人们环保意识的不断提高,回收利用已成为日常生活中不可或缺的一部分。回收小程序作为一种便捷、高效的回收方式,越来越受到人们的关注和喜爱。本文将探讨回收小程序的意义和作用,设计理念、功能特点、使用流程以及推广策略,并…...
568A和568B两种线序
现状 现在大家都是采用568B的线序 线序 标准568A:橙白-1,橙-2,绿白-3,蓝-4,蓝白-5,绿-6,棕白-7,棕-8 标准568B:绿白-1,绿-2,橙白-3&#x…...
kafka广播消费组停机后未删除优化
背景 kafka广播消息的时候为了保证groupId不重复,再创建的时间采用前缀时间戳的形式,这样可以保证每次启动的时候是创建的新的,但是 会出现一个问题:就是每次停机或者重启都会新建一个应用实例,关闭应用后并不会删除…...
Czkawka:用Rust构建的开源存储清理工具全解析
Czkawka:用Rust构建的开源存储清理工具全解析 【免费下载链接】czkawka Multi functional app to find duplicates, empty folders, similar images etc. 项目地址: https://gitcode.com/GitHub_Trending/cz/czkawka 一、场景痛点:当代存储管理的…...
船舶水动力学与运动控制技术指南:从理论建模到工程实践
船舶水动力学与运动控制技术指南:从理论建模到工程实践 【免费下载链接】FossenHandbook Handbook of Marine Craft Hydrodynamics and Motion Control is an extensive study of the latest research in marine craft hydrodynamics, guidance, navigation, and co…...
DeepSeek-V3 vs V3-Base:开发者如何根据项目需求选择最适合的模型?
DeepSeek-V3 vs V3-Base:开发者如何根据项目需求选择最适合的模型? 当你在GitHub上搜索代码补全工具,或是在Kaggle上寻找数学竞赛的解题思路时,可能会被各种AI模型的选择搞得眼花缭乱。作为开发者,我们需要的不是"…...
什么是焦糖布丁理论?用 JTBD 做软件产品设计的四步法
“焦糖布丁理论”其实是对 Jobs to Be Done(JTBD,待办任务理论) 的一种本土化、形象化的称呼,源自哈佛商学院教授 克莱顿克里斯坦森(Clay Christensen) 在其著作《与运气竞争》(Competing Again…...
6大维度深度测评:如何挑选最可靠的开源付费墙绕过工具?
6大维度深度测评:如何挑选最可靠的开源付费墙绕过工具? 【免费下载链接】bypass-paywalls-chrome-clean 项目地址: https://gitcode.com/GitHub_Trending/by/bypass-paywalls-chrome-clean 在数字阅读时代,优质内容的付费壁垒逐渐形成…...
10分钟搞定 Nginx 安装:Linux/Windows 双平台实测(附避坑指南)
一、前言上一篇我们初识了Nginx——知道了它是高性能的HTTP和反向代理服务器,懂了它为什么被99%的互联网公司青睐,也明确了我们后续的学习路线。本篇文章将手把手教你在Linux和Windows系统上,完成Nginx的安装、部署、启动、停止 ,…...
告别天价桥接芯片!用高云GW5AT-LV15MG132 FPGA搞定MIPI C-PHY摄像头测试盒
国产FPGA革新摄像头测试方案:高云GW5AT-LV15MG132的MIPI C-PHY实战解析 在摄像头模组生产线上,测试环节的成本与效率直接关系到企业竞争力。传统测试方案依赖进口FPGA搭配昂贵桥接芯片,不仅物料清单(BOM)成本居高不下…...
终极指南:buger/jsonparser如何10倍加速处理第三方API不确定性数据
终极指南:buger/jsonparser如何10倍加速处理第三方API不确定性数据 【免费下载链接】jsonparser One of the fastest alternative JSON parser for Go that does not require schema 项目地址: https://gitcode.com/gh_mirrors/js/jsonparser 在处理第三方AP…...
手把手教你用Cline插件5分钟搞定DeepSeek-R1模型接入(附硅基流动平台2000万Token福利)
5分钟极速上手:用Cline插件无缝对接DeepSeek-R1大模型实战指南 当你第一次听说只需要5分钟就能让一个强大的AI模型为你工作时,可能会觉得这像是某种夸张的营销话术。但作为一个曾经花了整整三天时间才搞定第一个模型接入的开发者,我可以负责任…...
35AE92 GJR5137200R0005电子模块
35AE92 GJR5137200R0005 电子模块是一款工业控制系统用的电子控制模块,通常用于西门子或ABB等自动化设备中,承担信号处理、控制逻辑执行及系统接口功能。开头:35AE92 GJR5137200R0005电子模块是工业自动化控制系统的重要组成部分,…...
