軟件須要在不一樣的環境中部署,代碼是保持不變的,可是不一樣的運行環境存在差別,因此須要使用配置適應不一樣的環境。好比:java
配置的原則是:代碼與配置要嚴格分離,不容許在代碼中使用常量保存配置。git
最多見的配置方式就是配置文件,按照配置文件的存儲位置,能夠分爲內部配置和外部配置:github
構建好的程序被部署在服務器上後,爲了解決故障、性能優化、適應新的需求,須要對服務器和應用的配置進行更改。若是直接登陸服務器修改某個配置,隨着時間的推移和管理的複雜化,就會引起配置漂移。spring
這種能夠直接登陸修改的服務器稱爲可變服務器。可變服務器會形成開發、測試、生產服務器不一致,生產環境中不一樣的節點也不一致,容易出現運行問題。docker
要防止配置漂移,服務器要禁止手動修改,只能經過自動化部署形式更改配置,這種服務器就叫不可變服務器。不可變服務器消除了不一致性,開發、測試環境中獲得的程序包和最終到達服務器的程序包是徹底相同的。這樣就能防止配置漂移。shell
生產環境使用如下幾配置種技術:數據庫
/etc
目錄,或者其餘合適的位置;refresh
端口,能夠調動這個端口在不重啓進程的狀況下修改配置項。示例程序演示了 Spring Boot 配置方式,打包運行:後端
mvn package
export message=bonjour
java -Dmessage=hello \
-jar spring-boot-config-sample-1.0.0-SNAPSHOT.jar \
--message=hi \
--spring.config.name=application,conf
message
配置出如今 4 個位置:性能優化
export message=bonjour
-Dmessage=hello
--message=hi
application.properties
啓動以後在 env
端口查看設置:服務器
$ curl http://localhost:8080/actuator/env
{
"propertySources": [ { "name": "commandLineArgs", "properties": { "message": { "value": "hi" } } }, { "name": "systemProperties", "properties": { "message": { "value": "hello" } } }, { "name": "systemEnvironment", "properties": { "message": { "value": "bonjour", "origin": "System Environment Property \"message\"" } } }, { "name": "applicationConfig: [classpath:/application.properties]", "properties": { "message": { "value": "nihao", "origin": "class path resource [application.properties]:9:9" } } } ] }
這裏刪掉了一些無關的內容,能夠看到 message
設置是按照 commandLineArgs
、systemProperties
、systemEnvironment
、applicationConfig
的順序加載的,以最早出現的爲準。
spring.config.name
啓動參數定義了配置文件的名稱。Spring Boot 默認的配置文件是 application.properties
,這裏添加了一個 conf.properties
。
Spring Boot 按照特定的順序加載配置項,位置和順序以下:
DevTool
定義的配置項@TestPropertySource
標籤訂義的配置項@SpringBootTest#properties
標籤訂義的配置項SPRING_APPLICATION_JSON
環境變量ServletConfig
定義的 init
參數ServletContext
定義的 init
參數-Dkey=value
定義,System.getProperties()
能夠查看到RandomValuePropertySource
定義的隨機值profile
的外部配置文件profile
的內部配置文件profile
的外部配置文件profile
的內部配置文件@Configuration
類型裏面的 @PropertySource
標籤訂義的配置SpringApplication.setDefaultProperties
方法設置的默認值內外部配置文件的加載位置和順序以下:
config
目錄.
當前目錄classpath:/config
classpath:/
使用 Dockerfile
是在生產環境建立 Docker 鏡像的惟一推薦方式,示例程序提供了 Dockerfile
樣例。Dockerfile
將運行包和配置文件複製到鏡像裏:
RUN mkdir -p /opt/stack
COPY target/spring-boot-config-sample-1.0.0-SNAPSHOT.jar /opt/stack/
COPY ./conf.properties /opt/stack/
在環境變量和啓動參數中注入配置項:
ENV message=bonjour
ENTRYPOINT ["java", \ "-jar", \ "spring-boot-config-sample-1.0.0-SNAPSHOT.jar", \ "--spring.config.name=application,conf"]
定義了健康檢查規則:
HEALTHCHECK --interval=30s --timeout=10s \
CMD curl -f http://localhost:8080/actuator/health || exit 1
Dockerfile
裏面還對鏡像系統進行了設置,提升了打開文件句柄數。Docker 是實現不可變服務器的最佳方式。
RUN ulimit -n 65536
使用 docker build
命令製做鏡像,第一次運行會下載一個 primetoninc/jdk
基礎鏡像,須要花一些時間:
docker build -t config-sample .
使用 docker run
命令運行程序:
docker run -it -p 8080:8080 config-sample
在實際環境上可使用 Kubernetes、Mesos 這樣的平臺管理和運行 Docker 鏡像,徹底能夠避免直接登陸服務器操做。