Spring Cloud Config配置文件最佳实践

原文地址

大多数Spring Cloud项目都会使用Spring Cloud Config来管理应用启动时的配置文件,同时开发人员面临着多样化的程序启动方式:操作系统进程启动、docker启动、k8s启动。那么如何规划这些配置文件以适应多种启动方式呢?本文尝试给出一些建议

先讲几个规则

  1. 程序打包时,要将bootstrap.propertiesapplication.properties(或者它们的yaml变种)打到包里。
  2. bootstrap.properties里,要针对可变配置项做环境变量化。
  3. application.properties里,要针对可变配置项做环境变量化。
  4. Spring Cloud应用关于Config Server的配置要放在bootstrap.properties里,并且要做环境变量化。
  5. Config Server所提供的application-*.properties里不得有环境变量。因为既然直接提供配置了,那么就不应该再使用环境变量。

要针对可变配置项做环境变量化

这句话对应The 12-factor App的Config章节。具体做法是在配置文件里使用placeholder。下面是两种方式:

app.name=${APP_NAME}
app.description=${APP_DESC:Default description}

第一种方式Spring Boot/Cloud应用在启动时,会根据这个顺序APP_NAME的值,如果找不到程序启动会报错。

第二种方式和第一种方式的不同在于如果找不到,则使用application.properties里定义的默认值。

而程序在启动时应该通过环境变量的方式将这些值传递进去。

在真实应用中应该尽量多的使用第二种方式,只有少数的配置才是程序启动时必须提供的,一般来说都是一些数据库连接字符串、用户名密码等信息。

Spring Cloud应用关于Config Server的配置要放在bootstrap.properties里,并且要做环境变量化。

比如这样:

spring.cloud.config.enabled=${CONFIG_ENABLED:true}
spring.cloud.config.profile=${CONFIG_PROFILE:production}
spring.cloud.config.label=${CONFIG_LABEL:master}
spring.cloud.config.uri=${CONFIG_SERVER_URL:http://config-server:8080/}

上面这个配置可以控制是否连接config server,因为在开发环境下我们可能并不需要config server。也提供了可以config server启动程序的可能。 同时也控制了如果连接config server,应该使用哪个application.properties

需要注意的是,如果我们选择程序启动的时候连接config server,那么在程序启动时提供的环境变量就只能是和config server相关的环境变量(在这个例子里就是上面的CONFIG_*),这些配置用来控制如何获得application.properties

因为此时程序所使用的配置都来自于config server,如果config server提供一些,环境变量又提供一些则会造成运维上的混乱。

各种启动方式

下面讲讲各种启动方式如何传递环境变量。

以操作系统进程启动

直接以操作系统进程启动的方法是类似于这样的:

APP_NAME=my-app APP_DESC="My App Desc" java -jar spring-cloud-app.jar

用Docker启动

用docker启动则是这样的,参见Docker ENV (environment variables)

docker run --name my-app -e APP_NAME=my-app -e APP_DESC="My App Desc" spring-cloud-app:latest

在K8S里启动

定义ConfigMap或Secret(用在密码类配置上),然后在Deployment spec里使用configMapRef或者secretRef或者configMapKeyRef 或者secretKeyRef,比如下面的例子:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  namespace: <namespace>
spec:
  ...
  template:
    ...
    spec:
      containers:
      - name: my-app
        image: <image repository>
        ...
        envFrom:
        - configMapRef:
            name: my-app-config
        - secretRef:
            name: my-app-secret
        env:
        - name: APP_NAME
          valueFrom:
            configMapKeyRef:
              name: my-app-config
              key: APP_NAME
        - name: APP_DESC
          valueFrom:
            secretKeyRef:
              name: my-app-secret
              key: APP_DESC

详见Configure a Pod to Use a ConfigMapSecretsLoad env variables from ConfigMaps and Secrets upon Pod boot

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏惨绿少年

KICKSTART无人值守安装

1.1 环境说明 [root@test ~]# cat /etc/redhat-release CentOS release 6.9 (Final) [roo...

30400
来自专栏Android先生

Gradle从入门到了解 - 简书

Gradle(英[g'reɪdl])是一个任务驱动型的构建工具,是一个依赖管理工具,更是一个编程框架。 它抛弃了基于XML的各种繁琐配置,取而代...

14430
来自专栏Java架构沉思录

揭秘JDBC超时机制

在遭到DDos攻击后,整个服务都垮掉了。由于第四层交换机不堪重负,网络变得无法连接,从而导致业务系统也无法正常运转。安全组很快屏蔽了所有的DDos攻击,并恢复了...

20530
来自专栏Netkiller

PHP 安全与性能

PHP 安全与性能 摘要 我的系列文档 Netkiller Architect 手札Netkiller Developer 手札Netkiller PHP 手札...

39050
来自专栏小狼的世界

在Centos 5.2下编译安装LAMP

首先使用Virtualbox安装一台CentOS 5.2的虚拟机,网络连接采用 Host-only Adapter,这样主客机之间可以互相访问,但是客机不能够上...

11220
来自专栏雪胖纸的玩蛇日常

django2+uwsgi+nginx上线部署到服务器Ubuntu16.04(最新最详细版)

36160
来自专栏菩提树下的杨过

redis 学习笔记(6)-cluster集群搭建

上次写redis的学习笔记还是2014年,一转眼已经快2年过去了,在段时间里,redis最大的变化之一就是cluster功能的正式发布,以前要搞redis集群,...

22050
来自专栏上善若水

005-centos7 搭建svn服务器

可以看到,没有telnet服务和3690端口。增加telnet服务器和3690端口:

34440
来自专栏曾倩倩的专栏

su命令cannot set groups: Operation not permitted的解决方法

问题场景: user_00@hadoop-10-125-224-102:> su root Password: su: cannot set groups:...

71580
来自专栏Zachary46

Android直接用手机打包apk!

本人用的是Mac,以下操作都是在Mac环境下配置的,Windows环境的配置移步到Android使用Jenkins自动化构建测试打包apk

46930

扫码关注云+社区

领取腾讯云代金券