1. 程式人生 > >使用Spring Cloud Config統一管理配置,別再到處放配置檔案了

使用Spring Cloud Config統一管理配置,別再到處放配置檔案了

# 1 前言 > 歡迎訪問[南瓜慢說 www.pkslow.com](https://www.pkslow.com/)獲取更多精彩文章! 可配置是一個成熟軟體系統應該提供的特性,而配置管理對於大型系統就顯得十分重要,特別是對於擁有多個應用的微服務系統。可喜的是,`Spring`為我們提供了很好的配置管理,如`Springboot`的配置就很強大。對於`Spring Cloud`,就有強大的`Spring Cloud Config`,在提供了一個在應用之外的配置管理,如檔案或`Git`倉庫,對分散式系統配置管理十分有益。 # 2 快速體驗 `Spring Cloud Config`服務端就是一個`Springboot`應用,啟動、部署都十分簡單。 整體的架構如下圖所示: ![](https://img2020.cnblogs.com/other/946674/202008/946674-20200823004436105-555030701.png) ## 2.1 服務端就是一個Springboot 在`Springboot`中新增依賴如下: ```xml ``` 只需要一個就行了,它已經包含了`web`和`actuator`。 新增`Java`主類: ```java package com.pkslow.config; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.config.server.EnableConfigServer; @SpringBootApplication @EnableConfigServer public class ConfigServer { public static void main(String[] args) { SpringApplication.run(ConfigServer.class,args); } } ``` 跟普通的`Springboot`應用相比只是多了一個註解`@EnableConfigServer`而已。 ## 2.2 配置倉庫 通過我們會把配置通過版本控制管理起來,一般使用`Git`倉庫,為簡單展示使用本地倉庫如下: ```bash # 建立目錄 mkdir git-repo # 初始化一個git目錄 git init # 新建檔案 touch application.properties # 新增變更 git add . # 提交變更 git commit -m "init" ``` 配置一下專案的`application.properties`,注意是`Config Server`專案的,而不是在`git-repo`目錄裡的: ```properties server.port=8888 spring.application.name=config-server spring.cloud.config.server.git.uri=/Users/pkslow/IdeaProjects/pkslow-modules/config-server/git-repo ``` 接著就可以啟動`Config Server`了。 但`git`倉庫裡的配置檔案沒有什麼內容,我們加入以下內容並提交(必須要提交,不然無法獲取)。 ```properties pkslow.webSite=www.pkslow.com pkslow.age=18 [email protected] ``` ## 2.3 配置路徑匹配 那我們如何獲取這些配置呢?可以通過以下`URL`讀取: ```bash /{application}/{profile}[/{label}] /{application}-{profile}.yml /{label}/{application}-{profile}.yml /{application}-{profile}.properties /{label}/{application}-{profile}.properties ``` - `label`指的是程式碼分支,如`master`,`feature-1`等。 - `application`是應用的名字,在以後客戶端讀取會用到。 - `profile`一般用於指定環境,如`prod`,`dev`,`uat`等。 所以,我們可以用以下`URL`來獲取我們剛新增的配置資訊: ```bash http://localhost:8888/application/default http://localhost:8888/application/default/master http://localhost:8888/master/application.properties http://localhost:8888/application-default.properties ``` 訪問如下: ```bash $ curl http://localhost:8888/application/default/master {"name":"application","profiles":["default"],"label":"master","version":"8796f39b35095f6e9b7176457eb03dd6d62b1783","state":null,"propertySources":[{"name":"/Users/pkslow/IdeaProjects/pkslow-modules/config-server/git-repo/application.properties","source":{"pkslow.webSite":"www.pkslow.com","pkslow.age":"18","pkslow.email":"[email protected]"}}]} ``` 最後一個地址`/{label}/{application}-{profile}.properties`的返回結果格式不同,直接返回配置檔案內容: ```bash $ curl http://localhost:8888/application-default.properties pkslow.age: 18 pkslow.email: [email protected] pkslow.webSite: www.pkslow.com ``` 如果我們先建一個分支`release-20200809`,並修改`age`為實際年齡`9`,則如下: ```bash $ curl http://localhost:8888/application/default/release-20200809 {"name":"application","profiles":["default"],"label":"release-20200809","version":"7e27e6972ed31ee1a51e9277a2f5c0a628cec67a","state":null,"propertySources":[{"name":"/Users/pkslow/IdeaProjects/pkslow-modules/config-server/git-repo/application.properties","source":{"pkslow.webSite":"www.pkslow.com","pkslow.age":"9","pkslow.email":"[email protected]"}}]} ``` 可以看到對應的`pkslow.age`已經變為`9`了,但訪問`/application/default/master`則還是`18`,分支之間不會相互影響。 ## 2.4 遠端倉庫 本地倉庫只是為了簡單展示,在實際專案中,一般使用遠端倉庫,在`GitHub`建立一個新的倉庫如下: ![](https://img2020.cnblogs.com/other/946674/202008/946674-20200823004436495-2129000366.png) 特意建立了個`private`的倉庫來檢測後面的鑑權是否正確。 重新配置倉庫的地址如下: ```properties spring.cloud.config.server.git.uri=https://github.com/pkslow/pkslow-config [email protected] spring.cloud.config.server.git.password=*** spring.cloud.config.server.git.default-label=master spring.cloud.config.server.git.search-paths=demo ``` 建立一個`demo`目錄來放置配置,所以`search-paths`配置為`demo`。完成配置重啟伺服器,就可以正常讀取遠端倉庫的配置了。 ## 2.5 多個程式碼配置倉庫 有些時候,我們的配置可能並不只在一個倉庫裡,而是在各自客戶端的程式碼庫中,比如我們有以下三個服務: - (1)服務發現:discovery,程式碼庫pkslow-discovery-service - (2)API閘道器:gateway,程式碼庫pkslow-gateway-service - (3)訂單服務:order,程式碼庫pkslow-order-service 它們各自的配置檔案都放在各自的程式碼庫裡,那就需要配置多個程式碼庫。我們還多配置一個預設的配置庫pkslow-default,如果匹配不到,就會選擇預設程式碼庫的配置。具體配置如下: ```yaml server: port: 8888 spring: application: name: config-server cloud: config: server: git: uri: /Users/pkslow/multiple-repos/pkslow-default repos: pkslow-discovery-service: pattern: pkslow-discovery-* cloneOnStart: true uri: /Users/pkslow/multiple-repos/pkslow-discovery-service search-paths: config pkslow-gateway-service: pattern: pkslow-gateway-*/dev cloneOnStart: true uri: /Users/pkslow/multiple-repos/pkslow-gateway-service search-paths: config pkslow-order-service: pattern: pkslow-order-* cloneOnStart: true uri: /Users/pkslow/IdeaProjects/pkslow-order-service search-paths: config ``` 可以各自定義配置檔案所放的目錄`search-paths`,不配置預設為根目錄。 這裡的`pattern`的配置規則是`{application}/{profile}`,支援正則符號`*`。注意只匹配一個結果,如果都滿足,只取第一個匹配的倉庫。 啟動後我們來看看配置結果: ```bash # 預設profile和label,正確匹配 $ curl http://localhost:8888/pkslow-order-service/default/master {"name":"pkslow-order-service","profiles":["default"],"label":"master","version":"9d86e5d11974f0a0e7c20cd53d8f062755193e70","state":null,"propertySources":[{"name":"/Users/pkslow/IdeaProjects/pkslow-modules/config-server/multiple-repos/pkslow-order-service/config/application.properties","source":{"pkslow.webSite":"www.pkslow.com","pkslow.app.name":"order-service"}}]} # 正確匹配,但不存在的Label,配置庫沒有對應程式碼分支,404 $ curl http://localhost:8888/pkslow-order-service/default/release {"timestamp":"2020-08-13T06:58:38.722+0000","status":404,"error":"Not Found","message":"No such label: release","path":"/pkslow-order-service/default/release"} # profile為dev,正確匹配 $ curl http://localhost:8888/pkslow-order-service/dev/master {"name":"pkslow-order-service","profiles":["dev"],"label":"master","version":"9d86e5d11974f0a0e7c20cd53d8f062755193e70","state":null,"propertySources":[{"name":"/Users/pkslow/IdeaProjects/pkslow-modules/config-server/multiple-repos/pkslow-order-service/config/application.properties","source":{"pkslow.webSite":"www.pkslow.com","pkslow.app.name":"order-service"}}]} # 對於gateway只能匹配profile=dev,無法匹配,讀取預設配置 $ curl http://localhost:8888/pkslow-gateway-service/default/master {"name":"pkslow-gateway-service","profiles":["default"],"label":"master","version":"8358f2b4701fac21a0c7776bc46cec6d9442c549","state":null,"propertySources":[{"name":"/Users/pkslow/IdeaProjects/pkslow-modules/config-server/multiple-repos/pkslow-base/application.properties","source":{"pkslow.birthDate":"2020-08-10"}}]} # 對於gateway只能匹配profile=dev,正確匹配 $ curl http://localhost:8888/pkslow-gateway-service/dev/master {"name":"pkslow-gateway-service","profiles":["dev"],"label":"master","version":"1a4e26849b237dc2592ca0d391daaa1a879747d2","state":null,"propertySources":[{"name":"/Users/pkslow/IdeaProjects/pkslow-modules/config-server/multiple-repos/pkslow-gateway-service/config/application.properties","source":{"pkslow.webSite":"www.pkslow.com","pkslow.app.name":"gateway-service"}}]} # 不存在的服務名,無法匹配,讀取預設配置 $ curl http://localhost:8888/unknown-service/dev/master {"name":"unknown-service","profiles":["dev"],"label":"master","version":"8358f2b4701fac21a0c7776bc46cec6d9442c549","state":null,"propertySources":[{"name":"/Users/pkslow/IdeaProjects/pkslow-modules/config-server/multiple-repos/pkslow-base/application.properties","source":{"pkslow.birthDate":"2020-08-10"}}]} ``` # 3 客戶端使用配置 經過前面的例子我們已經瞭解到服務端如何從程式碼庫裡獲取配置,但始終還是要使客戶端能獲取到對應的配置併產生效果。我們來演示一下。 ## 3.1 專案準備 搭建一個最簡單的`Springboot Web`專案,並加上`Spring Cloud Config`的支援,新增依賴如下: ```xml ``` 新增配置檔案:`bootstrap.properties`(雖然我們要從服務端讀取配置,但有些配置還是必須在客戶新增的,如服務端地址),內容如下: ```properties server.port=8080 spring.application.name=pkslow-gateway-service spring.cloud.config.uri=http://localhost:8888 ``` 在這裡我們配置了客戶端的埠、服務端的地址以及客戶端應用的名字,這個名字是非常關鍵的,待會講解。 新增`Controller`來暴露`API`以顯示讀到的配置內容: ```java @RestController public class PkslowController { @Value("${pkslow.age}") private Integer age; @Value("${pkslow.email}") private String email; @Value("${pkslow.webSite}") private String webSite; @GetMapping("/pkslow") public Map