配置动态化

在部署和测试 SpringBoot 应用时,会分环境、分架构,需要根据不同的场景指定动态参数。

配置加载

默认配置文件的查找路径:

  • file:./config/
  • file:./
  • classpath:/config/
  • classpath:/

配置文件放到 jar 包同层目录下,或是 config 子目录下,启动 jar 包加载配置文件实现配置项的覆盖。

1
2
3
4
├── app.jar
├── application.yml
└── config
└── appliaction.yml

spring.config.location 指定外部的配置文件

1
java -jar app.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties

命令参数

  • 运行时在 app.jar 后指定额外的 springboot 参数
  • 运行时在 app.jar 前指定 JVM 参数,可指定 springboot 内部处理的参数,或者程序内部对特定 jvm 参数处理的
1
2
3
4
5
6
7
# 指定钉钉报警的 token
java -jar -Ddingding.token=xxcxcxcxcxcxc app.jar
# 指定运行环境
java -jar app.jar --spring.profiles.active=prod

# 指定钉钉报警的 token,对应程序中获取该参数
java -jar app.jar --dingding.token=xxdfsdfdsf

环境变量

在配置文件中指定环境变量

配合 Docker 容器指定环境变量,实现不同环境的参数配置

1
2
3
4
5
6
#==========================================================
# datasource config
#==========================================================
spring.datasource.url=jdbc:mysql://${MYSQL_ADDR:172.17.10.127}:${MYSQL_PORT:3306}/test?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&allowMultiQueries=true&serverTimezone=Asia/Shanghai
spring.datasource.username=${DB_USER:root}
spring.datasource.password=${DB_PASS:test123}

静态变量

通过阿里的 arthas 工具,使用 ognl 表达式更改程序中的静态变量值,实现配置的动态化。

spring profile

spring 自带的环境区分,划分方式:

  • 在 resource 目录下定义 application-dev.yml, application-prod.yml 不同的文件进行区分
  • 通过在同一个文件中使用 --- 分开各个环境的内容

各个不同的环境对应的架构不同,如 redis 在测试环境使用单点的在生产环境使用 redis sentinel。

maven profile

根据不同环境编译打包的插件不一样,根据环境需要增加 maven deploy, maven docker 相关的插件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
<profiles>
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
</plugin>
</plugins>
</build>
</profile>

<profile>
<id>deploy</id>
<activation>
<property>
<name>deploy</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
</plugins>
</build>
</profile>

<profile>
<id>docker</id>
<activation>
<property>
<name>docker</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<executions>
<execution>
<id>build-image</id>
<phase>package</phase>
<goals>
<goal>build</goal>
</goals>
<configuration>
<dockerDirectory>${project.basedir}/src/main/docker</dockerDirectory>
<imageName>${docker.registry}/test/${project.artifactId}
</imageName>
<imageTags>
<imageTag>${project.version}</imageTag>
</imageTags>
<forceTags>true</forceTags>
<labels>
<label>VERSION=${project.version}</label>
</labels>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar
</include>
</resource>
</resources>
</configuration>
</execution>
<execution>
<id>push-image</id>
<phase>deploy</phase>
<goals>
<goal>push</goal>
</goals>
<configuration>
<serverId>${docker.server.id}
</serverId>
<imageName>
${docker.registry}/test/${project.artifactId}:${project.version}
</imageName>
<registryUrl><http://$>{docker.registry}</registryUrl>
<retryPushCount>3</retryPushCount>
<retryPushTimeout>60</retryPushTimeout>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>

Ref

24. Externalized Configuration