您好,登錄后才能下訂單哦!
概述
假設(shè)現(xiàn)在有個需求:
我們的應(yīng)用部署在10臺機器上,當(dāng)我們調(diào)整完某個配置參數(shù)時,無需重啟機器,10臺機器自動能獲取到最新的配置。
如何來實現(xiàn)呢?有很多種,比如:
1、將配置放置到一個數(shù)據(jù)庫里面,應(yīng)用每次讀取配置都是直接從DB讀取。這樣的話,我們只需要做一個DB變更,把最新的配置信息更新到數(shù)據(jù)庫即可。這樣無論多少臺應(yīng)用,由于都從同一個DB獲取配置信息,自然都能拿到最新的配置。
2、每臺機器提供一個更新配置信息的updateConfig接口,當(dāng)需要修改配置時,挨個調(diào)用服務(wù)器的updateConfig接口。
3、借助redis來實現(xiàn),把配置信息放置到redis上,但是這樣子,就每次都得去redis讀取,多了一些網(wǎng)絡(luò)請求。
上面這三種方法是最容易想到的,也很容易做,但是缺點當(dāng)然也非常的多。雖說缺點很多,但是某些傳統(tǒng)企業(yè)還真是這么干的。
在互聯(lián)網(wǎng)企業(yè)里,基本沒見過這么玩的,都是會使用分布式配置中心。用開源的或者自己實現(xiàn),目前開源的分布式配置中心有很多,而spring cloud config就是其中的佼佼者。下面我們就用spring cloud config來實現(xiàn)一個分布式配置中心。
是否使用最新的Spring Boot 2.0 版本
我曾經(jīng)使用最新的spring cloud 2.0做了一個分布式是配置中心的demo。原本以為很簡單,但是居然足足花了一天才搞定。有以下幾個原因:
1、spring cloud對應(yīng)的文檔沒有完全更新,出了問題,在文檔里找不著;
2、目前使用2.0版本的公司很少,網(wǎng)上也沒什么具體實戰(zhàn)文章介紹。出了問題后,百度是找不到解決方案的。而google也基本很難找到方案,都是一些零星的知識碎片;
3、2.0這個版本,config和bus這塊有些小變動,如果還按照1.5.x的版本來弄的話,是行不通的。
基于上面幾個原因,建議使用1.5.x的版本靠譜些。下面這篇文章會以下面的版本來介紹的:
spring boot:
1.5.2.RELEASE
對應(yīng)的spring cloud使用:
Dalston.RELEASE
搭建spring cloud config server
如果你只是想把配置統(tǒng)一由spring cloud config來管理,而暫時不想做配置中心的高可用的話,則只需要config和bus兩個組件就夠了。但是如果要保證高可用,還得使用spring cloud的注冊發(fā)現(xiàn)組件。
除了config和bus之外,我們還需要使用git。因為spring cloud config是使用git來做版本管理的。
基于spring cloud config做一個配置中心,很簡單,只要幾個小步驟就搞定了。
【1】引入config和bus組件
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency>
【2】啟動類使用@EnableConfigServer注解
package spring.cloud.config; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.config.server.EnableConfigServer; @EnableConfigServer @SpringBootApplication public class ConfigApplication { public static void main(String[] args) { SpringApplication.run(ConfigApplication.class, args); } }
【3】application.yml文件配置rabbitmq和git倉庫
server: port: 8040 spring: application: name: spring-cloud-config-server cloud: config: server: git: uri: https://gitlab.xxxxxx.com/config/xxxxxxx.git search-paths: username: xxxxx password: xxxxxx activemq: host: 127.0.0.1 port: 5672 username: guest password: guest management: security: enabled: false
配置RabbitMQ是因為bus組件需要使用它來通知客戶端,配置有變動。另外,記得使用
management: security: enabled: false
將驗證關(guān)閉掉,不然后面的操作,老是報授權(quán)錯誤。
到此服務(wù)端配置中心已經(jīng)搞定了。現(xiàn)在你就可以在服務(wù)端先做個小實驗,提交一個demo-dev.properties文件,文件的內(nèi)容如下:
address=hello
然后使用
http://localhost:8040/demo/dev
如果能輸出
{“address”:”hello”}
就說明spring cloud config跟git的交互是ok的。
客戶端接入配置中心
我們的目標(biāo):
當(dāng)把配置信息修改完提交到git上后,所有接入到spring cloud config的客戶端馬上能收到通知,并且拿到最新的配置信息。
下面介紹如何實現(xiàn)這個目標(biāo)。
客戶端只需要做幾個小步驟即可完成接入動作。
【1】引入依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency>
引入spring-boot-starter-web只是為了做實驗而已。
【2】配置RabbitMQ和引入配置中心的url
application.properties
spring.application.name=spring-cloud-config-client1 server.port=8042 management.security.enabled=false spring.rabbitmq.host=127.0.0.1 spring.rabbitmq.port=5672 spring.rabbitmq.username=guest spring.rabbitmq.password=guest
bootstrap.properties
spring.cloud.config.name=demo spring.cloud.config.profile=dev spring.cloud.config.label=master spring.cloud.config.uri=http://localhost:8040/
有三個注意點:
1、關(guān)閉驗證:management.security.enabled=false
2、spring cloud config相關(guān)的配置一定一定要放到bootstrap.properties里
3、使用spring.cloud.config.uri指定配置中心的地址
另外,對于客戶端來說,啟動類是不用加上任何跟config和bus有關(guān)的注解的。
到此客戶端搞定了,我們可以使用一個controller來開始做實驗了。
package springcloudconfig.client; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RefreshScope public class HelloController { @Value("${address}") private String address; @RequestMapping("/address") public String getAddress() { return this.address; } }
假設(shè)上面的HelloController需要用到address這個配置,只需要使用@RefreshScope和@value注解就可以了
@RefreshScope public class HelloController {}
@Value("${address}") private String address;
為了驗證客戶端是否能拿到最新的配置信息,提供一個
@RequestMapping("/address") public String getAddress() { return this.address; }
方法。
我們修改一下demo-dev.properties文件,將值改成
address=hello update
并提交到git上。這個時候我們調(diào)用getAddress接口
http://localhost:8041/address
發(fā)現(xiàn)并沒有拿到最新的值。那是因為push到git的這個動作做完后,我們沒有通知到spring cloud bus??梢允褂胮ostman來做一個post請求,調(diào)用如下接口,來通知bus。
http://localhost:8040/bus/refresh
這個接口一旦調(diào)用成功,bus會利用RabbitMQ通知所有的客戶端,配置已經(jīng)更新。
特別注意:
我們是調(diào)用服務(wù)端的/bus/refresh接口,不是去調(diào)用客戶端的/bus/refresh接口。
如果每次提交,都要去調(diào)用服務(wù)端的/bus/refresh接口,那這個也太麻煩了??梢允褂脀ebhook來幫一下忙。
如果你們用的是新的gitlab,那么只需要在工程里面,點擊【Settings】,再點擊【Integrations】,就可以設(shè)置webhook了,如下圖:
url里面填入配置中心服務(wù)端的/bus/refresh接口地址,然后點擊【添加Webhook】就可以了。
與攜程的阿波羅對比
Spring Cloud Config的精妙之處在于它的配置存儲于Git,這就天然的把配置的修改、權(quán)限、版本等問題隔離在外。通過這個設(shè)計使得Spring Cloud Config整體很簡單,不過也帶來了一些不便之處。
下面嘗試做一個簡單的小結(jié):
功能點 | Apollo | Spring Cloud Config | 備注 |
---|---|---|---|
配置界面 | 一個界面管理不同環(huán)境、不同集群配置 | 無,需要通過git操作 | |
配置生效時間 | 實時 | 重啟生效,或手動refresh生效 | Spring Cloud Config需要通過Git webhook,加上額外的消息隊列才能支持實時生效 |
版本管理 | 界面上直接提供發(fā)布歷史和回滾按鈕 | 無,需要通過git操作 | |
灰度發(fā)布 | 支持 | 不支持 | |
授權(quán)、審核、審計 | 界面上直接支持,而且支持修改、發(fā)布權(quán)限分離 | 需要通過git倉庫設(shè)置,且不支持修改、發(fā)布權(quán)限分離 | |
實例配置監(jiān)控 | 可以方便的看到當(dāng)前哪些客戶端在使用哪些配置 | 不支持 | |
配置獲取性能 | 快,通過數(shù)據(jù)庫訪問,還有緩存支持 | 較慢,需要從git clone repository,然后從文件系統(tǒng)讀取 | |
客戶端支持 | 原生支持所有Java和.Net應(yīng)用,提供API支持其它語言應(yīng)用,同時也支持Spring annotation獲取配置 | 支持Spring應(yīng)用,提供annotation獲取配置 | Apollo的適用范圍更廣一些 |
我個人還是推薦使用Spring Cloud Config,很輕量級、且社區(qū)活躍,遇到問題很好找到解決方案。另外呢,我個人認為阿波羅和Spring Cloud Config的區(qū)別就只是有木有界面而已。界面做得到的,我們通過git也可以的,只是用戶體驗沒那么好而已。
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對億速云的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。