Consul
是一個集配置管理、服務註冊和發現於一體的微服務基礎組件,它提供的這些功能咱們在微服務開發中都用到了。在實踐中,咱們發現Spring Cloud
沒有提供在啓動時自動加載某一個配置文件到Consul
配置中心的功能,因而參照Consul
社區的一個開源項目cfg4j-pusher進行了二次開發,實現了Spring Boot
應用啓動時自動加載指定配置文件到Consul
配置中心的功能。如下是軟件環境:html
在這裏我新建一個工程來講明實現過程,整個工程的結構以下:java
整個工程依照Spring Boot
工程的目錄結構建立,在com.consul.pusher
包下有四個類,其中ConsulApplication
的做用就不用說了,它是整個服務的啓動類。剩下的三個類說明以下:git
ConsulConfig
:提供加載配置到Consul
中的操做。它定義了一個私有的init
方法,這個方法被@PostConstruct
註解所標記,主要做用是在ConsulConfig
依賴注入完成以後讀取指定配置文件,將文件裏的配置信息推送到Consul
配置中心中。該方法在整個應用生命週期中只執行一次,定義爲私有的主要是不容許外部調用,保證安全性github
ConsulService
和ConsulServiceImpl
:ConsulServiceImpl
實現了ConsulService
接口,主要提供Consul
配置中心業務邏輯操做,它主要封裝了consul java client的一些方法。spring
resources
目錄下的bootstrap.yml
和application.yml
分別爲微服務全局配置文件和業務信息配置文件。在服務啓動期間,application.yml
配置文件的內容會被ConsulConfig
類的init
方法讀取並推送到Consul
配置中心。在這裏咱們沒有將bootstrap.yml
的文件內容推送到Consul
配置中心,主要是考慮到:數據庫
bootstrap.yml
裏定義的配置信息不常常修改apache
Spring Boot
天生不支持動態修改數據庫、ES
鏈接信息。bootstrap.yml
裏的定義的數據庫鏈接、ES
鏈接等信息經過Consul
配置中心修改後不能生效,還須要重啓應用才能生效。而且,須要修改數據庫鏈接、ES
鏈接信息的場景大部分是由於當前服務不可用產生的,服務的高可用不該由Consul
來維護bootstrap
通過與團隊成員討論,開發配置自動推送功能的初衷有兩個:api
方便devops
團隊進行自動化運維。微服務部署過程當中,配置的管理和修改是一件讓人頭疼的事情,不管是開發和運維,都但願減小手動修改配置的次數,經過自動推送配置功能,能夠輕鬆解決這個問題。Consul
官方雖然提供了HTTP API供使用者加載指定配置到Consul
中,可是須要開發給運維提供配置文件,再由運維手動執行命令加載這些配置文件到Consul
中,不只容易出錯,管理也不便安全
不管是分佈式服務仍是微服務,都應該有一套工具化、通用化的公共服務類庫。服務開發中,有不少重複的、能夠封裝成工具類的代碼,咱們能夠構建一個公共服務類庫,將這些代碼組織起來,供你們使用。這樣既解決了代碼重複的問題,也使服務更加健壯和高可用。業內優秀的例子好比Apache Commons、Google Guava系列類庫
基於第二點初衷,產品發佈了幾版以後,我將自動推送配置的代碼抽取了出來,封裝成一個公共服務類庫。封裝以後,工程目錄結構以下:
由於公共服務類庫不是一個可運行的微服務應用,它以jar
包的形式嵌入到微服務應用中,因此須要去除ConsulApplication
類,基礎庫單元測試經過以後,就能夠推送到咱們的maven
私服中。接下來,就是使用這個基礎庫了,使用步驟以下:
(1) 首先確保服務引入了Consul
依賴:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-consul-discovery</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-consul-config</artifactId> </dependency>
(2) 將自定義的配置統一提取到application.yml
裏。注意:yml
文件裏若是有空的value
值,請用單引號''
代替,不然yml
解析會報錯
(3) 在pom
文件裏引入consul-pusher
公共服務類庫,consul-pusher
類庫的Consul
配置加載類在服務啓動時自動加載配置到Consul
中:
<dependency> <groupId>com.consul.pusher</groupId> <artifactId>consul-pusher</artifactId> <version>1.0</version> </dependency>
(4) 在對應服務的Application
啓動類上,加入@ComponentScan(value = "com.consul.pusher")
,使公共類庫相關的類被Spring Boot
掃描到,好比:
@SpringBootApplication @EnableDiscoveryClient @EnableScheduling // 啓用定時調度功能,Consul須要使用此功能來監控配置改變 @ComponentScan(value="com.consul.pusher") public class ExampleApplication { public static void main(String[] args) { SpringApplication.run(ExampleApplication.class); } }
(5) 加載配置:
使用@Value
注入配置,在類上添加@RefreshScope
實現業務參數的熱更新:
@RefreshScope @Service public class StockMarketServiceImpl implements StockMarketService { private Logger logger = LoggerFactory.getLogger(this.getClass()); @Value(value = "${kline.host}") private String kLineHost; }
至此,整個工程的重構和使用完成。引入consul-pusher
的服務啓動後,在Consul
配置中心建立的配置信息截圖以下,以consul-pusher
服務自己爲例:
源碼連接:
GitHub:consul-pusher
Consul
整合參考連接: