本文将向大家介绍在SpringCloudAlibaba微服务架构中,如何实现多个微服务在不修改各自配置文件的情况下适配不同环境进行部署。
作者:后端小肥肠
1. 前言
在现代软件开发过程中,随着敏捷开发和持续集成的普及,开发团队越来越需要在多个环境中快速部署应用。这种需求促使开发者寻找更为灵活和高效的部署方案。尤其是在使用Spring Cloud Alibaba框架的项目中,如何在不修改配置文件的情况下实现环境的快速切换,成为了提高开发效率和降低环境导致的错误的关键。
2. 实现思路
2.1. SpringCloudAlibaba加载配置文件的顺序
Spring Cloud 通过 bootstrap.yml
和 application.yml
文件来加载应用程序的配置信息。这两个文件在 Spring Boot 应用程序中扮演着不同的角色,其加载顺序和原理如下:
2.1.1. 加载顺序:
-
bootstrap.yml:首先加载
bootstrap.yml
文件。这里可以定义一些系统级别的配置信息,比如连接远程配置中心的地址、加密/解密相关的配置等。 -
application.yml:然后加载
application.yml
文件。这里定义的是应用程序级别的配置信息,比如数据库连接信息、端口号等。
2.1.2. 加载的内容:
-
bootstrap.yml 的加载:
- 当 Spring Boot 应用程序启动时,首先会加载
bootstrap.yml
文件。 - 这个过程是在 Spring Boot 启动时的一个很早的阶段进行的。
bootstrap.yml
主要用于应用程序上下文创建之前需要的一些特殊配置,比如配置中心的地址、加密解密的相关配置等。
- 当 Spring Boot 应用程序启动时,首先会加载
-
application.yml 的加载:
- 一旦
bootstrap.yml
加载完成,接着加载application.yml
文件。 application.yml
文件包含了应用程序的各种配置,比如数据库配置、日志配置等。- 这些配置会在应用程序上下文创建后被加载。
- 一旦
2.2. 实现思路讲解
要实现在不修改配置文件情况下适配不同环境部署微服务,那么我们需要有一个common模块,common模块中有一个公共的配置文件,里面存放所有环境的Nacos配置信息:
如上图所示,下游服务只需要读取common模块中当前环境的配置信息,即可实现不修改配置文件的情况下快速适配各种环境进行部署(dev、test、prod)。
3. 开发环境搭建
3.1. 所需版本工具
依赖 | 版本 |
---|---|
Spring Boot | 2.6.3 |
Spring Cloud | 2021.0.1 |
Java | 1.8以上 |
Spring Cloud Alibaba | 2021.0.1.0 |
spring-cloud-starter-alibaba-nacos-discovery | 2021.0.1.0 |
spring-cloud-starter-alibaba-nacos-config | 2021.0.1.0 |
Nacos | 2.0.4 |
3.2. pom依赖
common模块依赖:
<dependencies>
<!--Nacos依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<exclusions>
<exclusion>
<groupId>com.netflix.ribbon</groupId>
<artifactId>ribbon</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
</dependencies>
下游微服务在pom中引入common模块即可:
<dependency>
<groupId>com.geoscene</groupId>
<artifactId>image-integration-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
4. 技术实践
4.1. common模块配置
在common模块resource文件夹下新增config文件夹,放入公共bootstrap.yml和application.yml:
编写公共bootstrap.yml:
# 本地开发环境
spring:
config:
activate:
on-profile: dev
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
username: nacos
password: nacos
namespace:
config:
server-addr: 127.0.0.1:8848
username: nacos
password: nacos
namespace:
file-extension: yaml
---
# 测试环境
spring:
config:
activate:
on-profile: test
cloud:
nacos:
discovery:
server-addr: 测试环境参数
username: 测试环境参数
password: 测试环境参数
namespace: 测试环境参数
config:
server-addr: 测试环境参数
username: 测试环境参数
password: 测试环境参数
namespace: 测试环境参数
file-extension: yaml
---
# 正式环境
spring:
config:
activate:
on-profile: prod
cloud:
nacos:
discovery:
server-addr: 正式环境参数
username: 正式环境参数
password: 正式环境参数
namespace: 正式环境参数
config:
server-addr: 正式环境参数
username: 正式环境参数
password: 正式环境参数
namespace: 正式环境参数
file-extension: yaml
编写公共application.yml:
spring:
mvc:
pathmatch:
# 该配置解决 Spring Boot 2.6.* 版本以上使用 Swagger 遇到的如下问题
# Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException
matching-strategy: ant_path_matcher
4.2. 下游微服务配置
下游微服务配置分为以下几个步骤:
1. pom中新增模块名称标签:
<name>image-integration-system</name>
2. pom中新增环境配置相关标签:
<profiles>
<profile>
<id>dev</id>
<properties>
<spring.profiles.active>dev</spring.profiles.active>
</properties>
<!--没有指定其他profile为激活状态时,该profile就默认会被激活-->
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>test</id>
<properties>
<spring.profiles.active>test</spring.profiles.active>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<spring.profiles.active>prod</spring.profiles.active>
</properties>
</profile>
</profiles>
3. 编写bootstrap.yml
spring:
application:
name: @project.name@
profiles:
active: ${spring.profiles.active}
4. 编写application.yml并抽离至Naocs
5. 启动类上新增@EnableDiscoveryClient注解
5. 系统运行
5.1. 本地运行
在本机环境中选择运行环境即可启动微服务
运行程序
5.2. 测试环境及生产环境运行(Docker)
编写Dockerfile
FROM java:8u111-jre-alpine as builder
ARG profile
ENV work_dir /home/code
WORKDIR ${work_dir}
ADD ./xx.jar ./xx.jar
FROM java:8u111-jre-alpine
ARG profile
ENV work_dir /home/code
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
WORKDIR ${work_dir}
COPY --from=builder ${work_dir}/xx.jar ./xx.jar
ENTRYPOINT ["java","-Dfile.encoding=utf-8","-jar", "-Xmx1536m","./xx.jar", "--spring.profiles.active=${profile}", "-c"]
编写Docker容器启动命令
docker run -id --name 容器名称 -p 端口号:端口号 --env profile=test 镜像名称:v1.0
6. 结语
本文讲解了如何在SpringCloudAlibaba中实现在不修改配置文件情况下适配不同环境部署的具体步骤,有这方面需求的同学可以根据文章进行具体实操,也欢迎在评论区留言进行技术探讨。