微服务, "spring cloud", "spring boot", "YAML", "application.yml"
微服务配置 springboot配置 配置模版化 配置外置
概述
- 即便是复杂的微服务工程,也离不开 DAO,SERVICE,API这些基础层级。
问题
-
构建一个微服务项目xxx-service,基础项目层级可能如下,
xxx-service // 这里common中的内容全部为module,为其他服务提供必要依赖 // xxx-web 与xxx-server,xxx-server2s 为两个单独的微服务,实际部署时可能对应两个独立运行的进程 xxx-common xxx-common-dao xxx--common-config xxx-web[Main] xxx-server[Main] xxx-server2[Main] ....
-
抛开module依赖关系,其实配置也存在一定的依赖关系,对于单一“微服务”而言配置可能包含以下几个部分内容,
- db相关配置
- 自身相关配置
- 其他配置
-
每个服务都可能包含这三部分,分别写在自己的 application.yml中,那么我们的项目会存在三份相同的配置,无论是开发还是 实际部署都会可能产生问题
- 修改一个忘记修改另一个;
- 调整配置麻烦,每个都需要去修改
- 开发 & 调试 困难,不容易区别 local & prod环境。
当然,如果你司有完善的 dev ops, 成套的CICD,各种统一配置,各种配置中心,那么这些问题也就容易规避了。
解决
-
问题原因在于配置文件中存在大量重复的内容,就像是把现有的微服务架构层次都放在一个module了一般。所以我们的目标如下,
- 提炼通用的公共配置,放在一个文件。
- 散落在每个module的配置,最好不需要经常修改。
- 简化部署过程中一些问题。
-
root目录新增一个空的config module,整体的服务结构看起来像是这样,
xxx-service // 这里common中的内容全部为module,为其他服务提供必要依赖 // xxx-web 与xxx-server,xxx-server2s 为两个单独的微服务,实际部署时可能对应两个独立运行的进程 xxx-common xxx-common-dao xxx--common-config xxx-web[Main] xxx-server[Main] xxx-server2[Main] xxx-config ....
让每个独立进程的
module
都依赖这个config module
之前的各类配置,我们提取公共配置。如这里提取出公共的db相关配置,在config module的resource目录下创建我们的db配置文件 命名为
application-db.yml
,里面放上我们的数据库相关配置。-
修改独立进程中的
application.yml
配置,移除这部分公共配置,并增加对db
这个配置模块的依赖.spring: profiles.active: db #与config module中application-后的名称相同
-
调整完毕后我们的db配置被提炼到了config这个module,解决了公共配置问题。可能你还有其他公共配置,那么不妨都建成独立的模块,统一放置在config中,然后在独立进程module中引入他们,例如,
#xxx-config/src/main/resources application-db.yml application-security.yml application-swagger.yml
spring: profiles.active: db,security,swagger #引入所有的配置
-
也可以把 各个独立进程的 module的 自定义配置也作为一个单独的模块放置在config module中,这样,实际部署过程中,可以把所有module的配置文件放在一起。最终的配置可能像是这样。
#xxx-config/src/main/resources application-db.yml application-security.yml application-swagger.yml application-web.yml application-server.yml application-server2.yml
xxx-web:application.yml
spring: profiles.active: db,security,swagger,web #引入所有的配置及自己的配置
xxx-server:application.yml
spring: profiles.active: db,security,swagger,server #引入所有的配置及自己的配置
xxx-server2:application.yml
spring: profiles.active: db,security,swagger,server2 #引入所有的配置及自己的配置
-
springboot配置文件外置,可以通过两种方式
- jar包同级目录创建名为
config
的文件夹,里面放置配置文件(无需额外增加其他配置,自动读取) -
jar -jar -Dloader.path=<配置文件存放目录路径>
,运行时增加参数指定配置文件路径。
- jar包同级目录创建名为
实际的微服务部署中,我们可能会将所有的 独立进程 module的 jar包放在同一个文件夹发布,使用不同的脚本去启动不同的微服务,那么配置方面就可以通过将config目录的所有配置文件外置即可,这样,ji提炼了公共配置,又区别了每个服务的各自的配置,岂不妙乎。
附录
多module打包后拷贝至外侧文件夹。
- 例如这里的xxx-web/pom.xml ."INSTALL"后拷贝至外侧的dist目录
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<echo>COPY artifact.</echo>
<copy file="target/${project.artifactId}-${project.version}.jar" tofile="../dist/${project.artifactId}-${project.version}.jar"/>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
config module配置文件拷贝
- 也拷贝至外侧的
dist
目录。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<echo>COPY Config.</echo>
<copy file="target/classes/prod/application-db.yml" tofile="../dist/config/application-db.yml"/>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
这样是不是只发布dist目录就好啦?吼方便的。