1. 配置中心Config
隨著項目日益龐大,每個項目都散落著各種配置文件,如果採用分布式的開發模式,需要的配置文件隨著服務增加而不斷增多。某一個基礎服務信息變更,都會引起一系列的更新和重啟,運維苦不堪言也容易出錯。配置中心就是是解決此類問題的。
市面上開源的配置中心有很多,BAT每家都出過,360的QConf、淘寶的diamond、網路鄭爛的disconf都是解決這類問題。國外也有很多開源的配置中心Apache Commons Configuration、owner、cfg4j等等。
為分布式系統中的基礎設施和微服務應用提供集中化的外部配置支持,它分為服務端與客戶端兩個部分。其中服務端也稱為分布式配置中心者叢滑,它是一個獨立的微服務應用,用來連接配置倉庫並為客戶端提供獲取配置信息、加密 / 解密信息等訪問介面;而客戶端則是微服務架構中的各個微服務應用或基礎設施,它們通過指定的配置中心來管理應用資源與業務相關的配置內容,並在啟動的時候從配置中心獲取和載入配置信息。
由於 Spring Cloud Config 實現的配置中心默認採用 Git 來存儲配置信息,所以使用 Spring Cloud Config 構建的配置伺服器,天然就支持對微服務應用配置信息的版本管理,並且可以通過 Git 客戶端工具來方便的管理和訪問配置內容。當然它也提供了對其他存儲方式的支持,比如:SVN 倉庫、本地化文件系統。
pom.xml中引入 spring-cloud-config-server 依賴,完整依賴配置如下:
創建Spring Boot的程序主類,並添加 @EnableConfigServer 註解,開啟Config Server
application.properties`中配置服務信息以及git信息,例如:
Spring Cloud Config也提供 本地存儲配置 方式。我們只需要設置屬性spring.profiles.active=native,Config Server會默認從應用的src/main/resource目錄下檢索配置文件。也可以通過spring.cloud.config.server.native.searchLocations=file:F:/properties/屬性來指定配置文件的位置。
准備一個 Git 倉庫,在 上面創建了一個文件夾 config-repo 用來存放配置文件,為了模擬生產環境,我們創建以下三個配置文件:
其中設置了一個from屬性,為每個配置文件分別設置了不同的值,如:
為了測試版本控制,在master中,我們都加入1.0的後綴,同時創建一個 config-label-test分支 ,並將各配置文件中的值用2.0作為後綴。
URL與配置文件的映射關系如下:
上首臘面的url會映射 {application}-{profile}.properties ** 對應的配置文件, {label} 對應git上不同的分支,默認為master。 先找給定名稱的配置文件,如果找不到去application.yml/application.properties找
嘗試構造不同的url來訪問不同的配置內容,比如:要訪問config-label-test分支,應用的prod環境,可以通過這個url: http://localhost:7001/application/prod/config-label-test
創建一個Spring Boot應用,在pom.xml中引入spring-cloud-starter-config依賴,完整依賴關系如下:
搭建srpingcloud-config server端,配置文件可以用application.yml 或 application.properties,config client端卻要使用bootstrap.yml或bootstrap.properties。
格外注意(config client端) :上面這些屬性必須配置在 bootstrap .properties中,config部分內容才能被正確載入。因為config的相關配置會先於application.properties,而 bootstrap.properties的載入也是先於application.properties (bootstrap.yml 的載入也是先於 application.yml)。
創建一個Rest Api來返回配置中心的from屬性,具體如下:
啟動該應用,並訪問: http://localhost:6020/from ,我們就可以根據配置內容輸出對應環境的from內容了。
有時,我們需要對配置內容做一些實時更新。server端會自動讀取最新提交的內容,client端不會自動獲取新的信息。
將config-server和config-client都啟動起來,並訪問客戶端提供的REST API http://localhost:6020/from 來獲取配置信息,可以獲得返回內容為: git-dev-1.0 。接著,我們可以嘗試使用Git工具修改當前配置的內容,比如,將 config-repo/application-dev.properties 中的from的值從 from=git-dev-1.0 修改為 from=git-dev-2.0 ,再訪問 http://localhost:6020/from ,可以看到其返回內容還是 git-dev-1.0 。
下面進行改造:在config-client端增加一些內容和操作以實現配置的刷新
在config-clinet的 pom.xml 中新增 spring-boot-starter-actuator 監控模塊,其中包含了 /refresh 刷新API。
增加spring-boot-starter-actuator 包,這是一套監控的功能,可以監控程序在運行時狀態,其中就包括 /actuator/refresh`的功能。
需要給 載入變數的類上 面載入 @RefreshScope ,在客戶端執行 /actuator/refresh 的時候就會更新此類下面的變數值。
Spring Boot 1.5.X 以上默認開通了安全認證,所以要在配置文件 application.yml 中添加以下配置以將 /actuator/refresh 這個 Endpoint 暴露出來
改造完之後,我們以 POST 請求的方式來訪問 http://localhost:6020/actuator/refresh 就會更新配置文件至最新版本。
載入 bootstrap. ------>連接config server 載入遠程設置 --------> 載入application.的配置**
bootstrap 放一些你不想改的值
本地配置和遠程配置沖突 以遠程的為准
2. Disconf原理及分布式配置中心的一般實現思路
因為新公司沒有採用獨立的配置中心,每次修改配置參數只能通過手動修改配置文件的方式,然後再重啟重啟重啟,而且機器又是多台,這種方式無疑是非常低下的,而且極容易出錯,所以才有了下面的配置中喊陪心選型。
其實自己開發一個簡單的配置中心也是非常容易的,基於redis+DB就能簡單實現。但是要設計一個合格的配置中心還需要考慮如下幾點:
所以要自己開發一個獨立的配置中心,還是要考慮得比較全面的。而且項目還是以業務為主,也沒有足夠人力來重新開發一套配置中心,所以就打算藉助於開源的力量來滿足目前的使用場景。
因為現在的配置中心還是有一些開源實現的。像網路的Disconf,阿里的Diamond,攜程的Apollo,還有基於Github的pull模式來實現。我為什麼選擇Disconf,主要有下面幾個點的考量:
Disconf是網路的一個分布式配置中心,目前已經開源。而且它是基於java實現的,有簡單的配置頁面,而且官方還提供了一個相對完善的 文檔 .開發者只需按照它上面的步驟來即可安裝,但是官網的安裝文檔比較扯淡,總結起來就是如下幾點:
然後啟動Nginx.
Disconf主要是依靠zookeeper的Watch機制來做配置實時修改的,我們都知道ZK是通過目錄掛載的方式來做服務的自粗滲攔動注冊與發布。客戶端啟動時注冊了一個回調介面,當zk目錄發生變化時會回調所有客戶端節點,從而做到"實時"更新配置的目的。
在配置中心添加的配置數據都被持久化到了DB中,每次客戶端啟動的時候會調用Disconf的Http介面獲取最新的配置數據,如果網路不通,默認會重試三次,如果還不通,則拋出異常。如果第一次拉取配置就有問題,作為配置中心來講是肯定是無解的,需要客戶端去解決(一般這種情況是網路問題或者配置中心服務不可用導致)。
我們這里不需要考慮第一次載入配置就失敗的情況.那麼問題來了:
答案:不會,因為disconf會單獨起一個線程做重連操作。岩胡
答案:沒有做這方面的保證。因為客戶端連接到配置中心上以後會將機器名掛載到zk目錄下,可以通過界面查看配置使用的機器數。
所以要使用一個開源產品,還是要盡可能的掌握它,如果有太多未知因素在裡面的話,出了問題很難被發現,對自己也是一個提升。
3. Apollo配置中心 原理分析
大致過程:
①笑談謹 用戶在Portal操作配置發布
② Portal調用Admin Service的介面操作發布
③ Admin Service發布配置後,發送ReleaseMessage給各個Config Service
④ Config Service收到ReleaseMessage後,通知對應的客戶端
發送侍顫ReleaseMessage的實現方式
Config Service通知客戶端的實現方式
實現原理:
① 客戶端和服務端保持了一個長連接,從而能第一時間獲得配置更新的推送。(通過Http Long Polling實現)
② 客戶端還會定時從Apollo配置中心服務端拉取應用的最新配置。
Apollo在Spring環境下實現配置優先順序原理
此種引入apollo-client客戶端之後,啟動類加上@EnableApolloConfig,如果有涉及到屬性發布,即可刷新
以碰基@ConfigurationProperties得形式得屬性,需要額外添加監聽器Bean,方法上加上註解@ApolloConfigChangeListener。例如:
4. 簡述軟體配置的管理中心思想
(1)《ISO/IEC 12207(1995)信息技術--軟體生存期過程》:配置管理過程是在整個軟體生存期中實施管理和技術規程的過程,它標識、定義系統中軟體項並制定基線;控制軟體項的修改和發行;記錄和報告軟體項的狀態和修改申請;保證軟體項的完整性、協調性和正確性;以及控制軟體項的儲存、裝載和交付。
(2)《ISO 9000-3(1997)質量管理和質量保證標准--第3部分:ISO 9001:1994 在計算機軟體開發、供應、安裝和維山稿肆護中的使用指南》:軟體配置管理是一個管理學科,它對配置項的開發和支持生存期給予技術上和管理上的指導。配置管理的應用取決於項目的規模、復雜程度和風險大逗轎小。(3)巴比齊(W.BaBIch):軟體配置管理能協調軟體開發,使得混亂減少到最小。軟體配置管理是一種標識、組織和控制修改的技術,目的是最有效地提高生產率。
(4)《GB/T 11457(1995)軟體工程術語》:軟體配置管理是標識和確定系統中配置項敬困的過程,在系統整個生存周期內控制這些項的投放和更動,記錄並報告配置的狀態和更動要求,驗證配置項的完整性和正確性。一言以蔽之,配置管理是門通過一系列技術、方法和手段來維護產品的歷史、鑒別和定位產品獨有的版本、在產品開發和發布階段控制變化,從而使管理制度化、有效減少重復性工作、保證產品的質量和效率的科學。
5. Spring Cloud 之配置中心
配置伺服器默認採用git來存儲配置信息,也可以本地存儲。
1. pom.xml中加入spring-cloud-config-server,spring-cloud-starter-eureka
2. 主類中配置@EnableConfigServer @EnableEurekaClient
3. application.yml配置
spring.application.name=config-server
server.port=60002
eureka.client.serviceUrl.defaultZone=http://localhost:10001/eureka/
4. 若租緩使用本地存儲:
spring.profiles.active=native
spring.cloud.config.server.native.search-locations=classpath:/config
在resource目錄下創建config目錄,裡面配置clientA-dev.yml,clientA-test.yml等
5. 若使用git存儲:
spring.cloud.config.server.git.uri=http://git.oschina.net/didispace/SpringBoot-Learning/
spring.cloud.config.server.git.searchPaths=Chapter9-1-4/config-repo
spring.cloud.config.server.git.username=username
spring.cloud.config.server.git.password=password
uri:配置git倉庫位置;searchPaths:配置倉庫路徑下的相對搜索位置,可以配置多個;username:訪問git倉庫的用戶名;password:訪問git倉庫的用戶密碼
1. pom.xml中加入spring-cloud-starter-eureka,spring-cloud-starter-config
2. spring.application.name=clientA
spring.cloud.config.enabled=true
spring.cloud.config.discovery.enabled=true
spring.cloud.config.discovery.service-id=config-server
spring.cloud.config.profile=dev
spring.cloud.config.label=master
eureka.client.serviceUrl.defaultZone=http://localhost:10001/eureka/
解釋:
配置中心的{application}-{profile}.properties配置文件,{label}對應git上不同的分支,默認為master。
spring.application.name:對應{application}部分
spring.cloud.config.profile:對應{profile}部分
spring.cloud.config.label:對應git的分支。如果配滾首置中心使用的是本地存儲,則該參數無用
spring.cloud.config.uri:配置中心的具體地址(不建議使用,因為不利於負載均衡)
spring.cloud.config.discovery.service-id:指定配置中心的service-id,便於擴展為高可用配置集群。
特別注意:上面這些與弊備模spring-cloud相關的屬性必須配置在bootstrap.properties中,config部分內容才能被正確載入。因為config的相關配置會先於application.properties,而bootstrap.properties的載入也是先於application.properties。例如上面的defaultZone如果不配置,則找不到service-id,會導致啟動失敗。
1. config-server主類配置@EnableEurekaClient,並啟動多個,相當於有多個配置中心注冊在服務中心;
2. config-client的properties配置中使用spring.cloud.config.discovery.service-id指定config-server,實現負載均衡。如此,任意一個config-server節點crash了也不影響config-client的運行。
配置中心的數據修改後,客戶端可實時獲取更新內容,實現方式:
1. config-client的pom.xml中新增spring-boot-starter-actuator監控模塊,其中包含了/refresh刷新API。
2. git中配置數據修改後,config-client中執行http://localhost:18443/refresh 即可實現client端配置數據更新
實例源碼: config-server