大多数Spring Cloud项目都会使用Spring Cloud Config来管理应用启动时的配置文件,同时开发人员面临着多样化的程序启动方式:操作系统进程启动、docker启动、k8s启动。那么如何规划这些配置文件以适应多种启动方式呢?本文尝试给出一些建议
先讲几个规则
- 程序打包时,要将
bootstrap.properties
和application.properties
(或者它们的yaml变种)打到包里。 bootstrap.properties
里,要针对可变配置项做环境变量化。application.properties
里,要针对可变配置项做环境变量化。- Spring Cloud应用关于Config Server的配置要放在
bootstrap.properties
里,并且要做环境变量化。 - Config Server所提供的
application-*.properties
里不得有环境变量。因为既然直接提供配置了,那么就不应该再使用环境变量。
要针对可变配置项做环境变量化
这句话对应The 12-factor App的Config章节。具体做法是在配置文件里使用placeholder。下面是两种方式:
|
|
第一种方式Spring Boot/Cloud应用在启动时,会根据这个顺序找APP_NAME
的值,如果找不到程序启动会报错。
第二种方式和第一种方式的不同在于如果找不到,则使用application.properties
里定义的默认值。
而程序在启动时应该通过环境变量的方式将这些值传递进去。
在真实应用中应该尽量多的使用第二种方式,只有少数的配置才是程序启动时必须提供的,一般来说都是一些数据库连接字符串、用户名密码等信息。
Spring Cloud应用关于Config Server的配置要放在bootstrap.properties里,并且要做环境变量化
比如这样:
|
|
上面这个配置可以控制是否连接config server,因为在开发环境下我们可能并不需要config server。也提供了可以config server启动程序的可能。
同时也控制了如果连接config server,应该使用哪个application.properties
。
需要注意的是,如果我们选择程序启动的时候连接config server,那么在程序启动时提供的环境变量就只能是和config server相关的环境变量(在这个例子里就是上面的CONFIG_*
),这些配置用来控制如何获得application.properties
。
因为此时程序所使用的配置都来自于config server,如果config server提供一些,环境变量又提供一些则会造成运维上的混乱。
各种启动方式
下面讲讲各种启动方式如何传递环境变量。
以操作系统进程启动
直接以操作系统进程启动的方法是类似于这样的:
|
|
用Docker启动
用docker启动则是这样的,参见Docker ENV (environment variables):
|
|
在K8S里启动
定义ConfigMap或Secret(用在密码类配置上),然后在Deployment spec里使用configMapRef
或者secretRef
或者configMapKeyRef
或者secretKeyRef
,比如下面的例子:
|
|
详见Configure a Pod to Use a ConfigMap、Secrets和Load env variables from ConfigMaps and Secrets upon Pod boot。
评论