Spring Cloud Config配置文件最佳實踐

原文地址html

大多數Spring Cloud項目都會使用Spring Cloud Config來管理應用啓動時的配置文件,同時開發人員面臨着多樣化的程序啓動方式:操做系統進程啓動、docker啓動、k8s啓動。那麼如何規劃這些配置文件以適應多種啓動方式呢?本文嘗試給出一些建議java

先講幾個規則

  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。下面是兩種方式:git

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

第一種方式Spring Boot/Cloud應用在啓動時,會根據這個順序APP_NAME的值,若是找不到程序啓動會報錯。github

第二種方式和第一種方式的不一樣在於若是找不到,則使用application.properties裏定義的默認值。spring

而程序在啓動時應該經過環境變量的方式將這些值傳遞進去。docker

在真實應用中應該儘可能多的使用第二種方式,只有少數的配置纔是程序啓動時必須提供的,通常來講都是一些數據庫鏈接字符串、用戶名密碼等信息。數據庫

Spring Cloud應用關於Config Server的配置要放在bootstrap.properties裏,而且要作環境變量化。

好比這樣:bootstrap

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.propertiesapi

須要注意的是,若是咱們選擇程序啓動的時候鏈接config server,那麼在程序啓動時提供的環境變量就只能是和config server相關的環境變量(在這個例子裏就是上面的CONFIG_*),這些配置用來控制如何得到application.propertiesapp

由於此時程序所使用的配置都來自於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

相關文章
相關標籤/搜索