优雅地切换SpringCloud注册中心

发布时间 2023-09-12 19:35:34作者: iminifly

背景

做项目时偶尔需要切换注册中心,虽然切换很简单,但如果项目研发伊始没有考虑切换的问题,就需要去拉分支,做配置,不够优雅。

springCloud支持很多注册中心,这里只介绍三个常用的:Eureka、Nacos、Consul

原理

利用maven profile来处理不同的注册中心以及依赖;

pom.xml样例

详见50-105行、124-137行

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
  
    <groupId>cn.rsmis</groupId>
    <artifactId>rs-produce-service</artifactId>
    <version>${revision}</version>

    <properties>
        <!-- COMPILE -->
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>

        <!-- Spring Cloud 依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>
        <!-- ./Spring Cloud 依赖 -->

        <!-- Spring web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>jakarta.servlet</groupId>
            <artifactId>jakarta.servlet-api</artifactId>
            <version>6.0.0</version>
            <scope>provided</scope>
        </dependency>
        <!-- ./Spring web -->

        <!-- 测试 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- ./测试 -->       

    </dependencies>

    <!-- 根据需要使用不同的注册中心, 或者不使用 -->
    <profiles>
        <profile>
            <!-- 唯一不重复的 -->
            <id>consul</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <!-- 这里与id保持一致 -->
                <current.env>consul</current.env>
            </properties>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-starter-consul-all</artifactId>
                </dependency>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-actuator</artifactId>
                </dependency>
            </dependencies>
        </profile>
        <profile>
            <id>nacos</id>
            <properties>
                <current.env>nacos</current.env>
            </properties>
            <dependencies>
                <dependency>
                    <groupId>com.alibaba.cloud</groupId>
                    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
                </dependency>
                <dependency>
                    <groupId>com.alibaba.cloud</groupId>
                    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
                </dependency>
            </dependencies>
        </profile>
        <profile>
            <id>eureka</id>
            <properties>
                <current.env>eureka</current.env>
            </properties>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
                </dependency>
            </dependencies>
        </profile>
    </profiles>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <!-- 解决java -jar命令找不到main类的问题 -->
                            <goal>repackage</goal>
                            <goal>build-info</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>

        <resources>
            <resource>
                <directory>src/main/resources/config</directory>
                <!--resource的filtering属性用来表示资源文件中的占位符是否需要被替换,true为需要替换-->
                <filtering>true</filtering>
                <!--引入资源文件信息-->
                <includes>
                    <include>application.yml</include>                    
                    <include>application-${current.env}.yml</include>
                    <include>bootstrap.yml</include>
                    <include>bootstrap-${current.env}.yml</include>
                </includes>
            </resource>
        </resources>

</project>

使用环境

命令行

直接使用mvn的-P参数
-Pxxx 激活 id 为 xxx 的 profile (如有多个,用逗号隔开)
例如要激活nacos和jdk-1.8两个profile 打包工程

mvn clean package -Pnacos,jdk-1.8

使用IDE

IDEA

这里以idea为例,打开maven工程后右上角maven工具来会将当前工程可用的profile罗列出来供我们勾选,如下:
image.png
我们只需要勾选对应的profile即可动态切换注册中心,并且package时也只会将勾选的注册中心依赖打包;
同理配置文件也可以做同样的处理
image.png

Eclipse

eclipse也支持maven profile只是没有像idea一样将可用的profile罗列出来;
image.png
image.png