微服務中配置中心Config+消息總線Bus,實現分佈式自動刷新配置

技術/楊33

一、分佈式配置中心Config

一套集中的、動態的配置管理,實現統一配置微服務中的每個子服務。

Spring Cloud Config為微服務架構提供了集中化的外部配置支持,配置服務器為各個不同微服務應用的所有環境提供一個中心化的外部配置

Config分為服務端和客戶端:

服務端,也就是分佈式配置中心,是一個獨立的微服務應用,用來連接配置服務器併為客戶端獲取配置信息。客戶端,通過指定的配置中心來管理應用資源。

Spring Cloud默認採用GitHub來存儲配置信息,這樣有助於對環境配置進行版本管理。

二、Config服務端讀取配置

1、在GitHub中新建一個文件夾,添加配置文件config-dev.yml

GitHub倉庫

config-dev.yml的內容為:

<code>config: info: "master,dev.yml"/<code>

2、新建module:cloud-config3344

pom.xml文件內容:

<code> org.springframework.cloud spring-cloud-config-server org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-actuator org.springframework.boot spring-boot-devtools runtime true cloud-common-util com.project.cloud 1.0-SNAPSHOT org.springframework.cloud spring-cloud-starter-netflix-eureka-client /<code>application.yml配置文件內容:

<code>server: port: 3344 spring: application: name: cloud-config-center cloud: config: server: git: uri: https://github.com/yangjian433/springcloud-config.git #git倉庫的地址 search-paths: - springcloud-config label: master #讀取分支 eureka: client: register-with-eureka: true #true表示向註冊中心註冊自己 fetch-registry: true #是否從EurekaServer抓取已有的註冊信息 service-url: #defaultZone: http://localhost:7001/eureka/ #單機服務註冊中心的地址 defaultZone: http://eureka7001.com:7001/eureka/ #集群服務/<code>主啟動類

<code>package com.cloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.config.server.EnableConfigServer; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; /** * @author 楊33 * @date 2020/5/2 12:40 */ @SpringBootApplication @EnableEurekaClient @EnableConfigServer public class ConfigCenterMain3344 { public static void main(String[] args) { SpringApplication.run(ConfigCenterMain3344.class, args); } }/<code>添加host文件映射

<code>127.0.0.1 config-3344.com/<code>

3、啟動主類:ConfigCenterMain3344

訪問地址:http://config-3344.com:3344/master/config-dev.yml,讀取GitHub上的配置文件信息。

三、Config客戶端讀取配置

上面服務端已經與GitHub直接連接,那麼這塊只要通過搭建的客戶端訪問服務端,就可以實現間接訪問GitHub配置信息。

1、新建module:cloud-config-client3355

pom.xml文件內容:

<code> org.springframework.cloud spring-cloud-starter-config /<code>bootstrap.yml配置文件內容:bootstrap.yml比application.yml的優先級別高,屬於優先加載。

<code>server: port: 3355 spring: application: name: cloud-config-client cloud: config: label: master #master分支 name: config #配置文件名稱 profile: dev #讀取後綴名稱,比如config-dev.yml、config-test.yml uri: http://localhost:3344 #配置中心地址 eureka: client: register-with-eureka: true #true表示向註冊中心註冊自己 fetch-registry: true #是否從EurekaServer抓取已有的註冊信息 service-url: #defaultZone: http://localhost:7001/eureka/ #單機服務註冊中心的地址 defaultZone: http://eureka7001.com:7001/eureka/ #集群服務/<code>接口業務類

<code>package com.cloud.controller; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; /** * @author 楊33 * @date 2020/5/2 13:29 */ @RestController public class ConfigClientController { @Value("${config.info}") private String configInfo; @GetMapping("/getConfigInfo") public String getConfigInfo() { return configInfo; } }/<code>主啟動類

<code>package com.cloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; /** * @author 楊33 * @date 2020/5/2 13:27 */ @SpringBootApplication @EnableEurekaClient public class ConfigClientMain3355 { public static void main(String[] args) { SpringApplication.run(ConfigClientMain3355.class, args); } }/<code>

2、啟動主啟動類ConfigClientMain3355

訪問接口地址:http://localhost:3355/getConfigInfo

四、手動刷新GitHub上配置文件的修改,避免了客戶端多次重啟服務

1、pom.xml文件引入actuator監控

<code> org.springframework.boot spring-boot-starter-actuator /<code>

2、bootstrap.yml添加暴露監控端點

<code>#暴露監控端點 management: endpoints: web: exposure: include: "*"/<code>

3、業務類ConfigClientController添加刷新能力註解@RefreshScope

<code>@RestController @RefreshScope public class ConfigClientController { @Value("${config.info}") private String configInfo; @GetMapping("/getConfigInfo") public String getConfigInfo() { return configInfo; } }/<code>

4、命令行手動刷新端口。這最後一步執行完,才能實現在GitHub上修改配置文件,客戶端cloud-config-client3355請求接口,修改立即生效,否則查出來的內容還是修改之前的。

<code>curl -X POST "http://localhost:3355/actuator/refresh"/<code>

查出來修改之後的文件內容

五、消息總線是什麼

在微服務架構中,通常會使用輕量級的消息代理來構建一個共用的消息主題,並讓系統中所有的微服務實例都連接上來。由於該主題中產生的消息會被所有的實例監聽和消費,所以稱它為消息總線。

在總線上的各個實例,都可以便捷的廣播一些需要消息,讓該主題上連接的其他實例知道。

六、分佈式自動刷新配置文件:消息總線Spring Cloud Bus

如果服務數量很多,手動刷新配置文件肯定是人力消耗非常大,不現實,那麼自動刷新配置就解放了人力,提高了效率。

Spring Cloud Bus能管理和傳播分佈式系統間的消息,用於廣播狀態更改、事件推送等。

Bus支持兩種消息代理:RabbitMQ和Kafka。本次以RabbitMQ為例開發測試:

1、在ConfigServer模塊cloud-config3344上修改幾處代碼配置:

pom.xml文件,添加內容:

<code> org.springframework.cloud spring-cloud-starter-bus-amqp /<code>application.yml文件,添加內容:rabbitmq節點和暴露端點配置

<code>server: port: 3344 spring: application: name: cloud-config-center cloud: config: server: git: uri: https://github.com/yangjian433/springcloud-config.git #git倉庫的地址 search-paths: - springcloud-config label: master #讀取分支 rabbitmq: addresses: 192.168.109.130 username: guest password: guest port: 5672 #暴露監控端點 management: endpoints: web: exposure: include: "bus-refresh" eureka: client: register-with-eureka: true #true表示向註冊中心註冊自己 fetch-registry: true #是否從EurekaServer抓取已有的註冊信息 service-url: #defaultZone: http://localhost:7001/eureka/ #單機服務註冊中心的地址 defaultZone: http://eureka7001.com:7001/eureka/ #集群服務/<code>

2、在ConfigClient模塊cloud-config-client3355上修改幾處代碼配置:

pom.xml文件,添加內容:

<code> org.springframework.cloud spring-cloud-starter-bus-amqp /<code>bootstrap.yml文件,添加內容:rabbitmq節點和暴露端點配置

<code>server: port: 3355 spring: application: name: cloud-config-client cloud: config: label: master #master分支 name: config #配置文件名稱 profile: dev #讀取後綴名稱,比如config-dev.yml、config-test.yml uri: http://localhost:3344 #配置中心地址 rabbitmq: addresses: 192.168.109.130 username: guest password: guest port: 5672 eureka: client: register-with-eureka: true #true表示向註冊中心註冊自己 fetch-registry: true #是否從EurekaServer抓取已有的註冊信息 service-url: #defaultZone: http://localhost:7001/eureka/ #單機服務註冊中心的地址 defaultZone: http://eureka7001.com:7001/eureka/ #集群服務 #暴露監控端點 management: endpoints: web: exposure: include: "*"/<code>

3、啟動ConfigServer和ConfigClient的主啟動類

4、修改GitHub上的配置文件內容

<code>config: info: "master,dev.yml,+2"/<code>

此時在沒有執行刷新端口命令,ConfigClient服務器還是查詢到修改前的數據。

5、只需刷新ConfigServer這一臺服務的端口,多個ConfigClient服務器都可以立即查詢到GitHub上修改後的配置文件內容。

刷新ConfigServer這一臺服務的端口的命令是:

<code>curl -X POST "http://localhost:3344/actuator/bus-refresh"/<code>

查詢到修改後的數據

上面是使用RabbitMQ做消息代理,才實現一處刷新,到處可用的功能,它的原理就是:

當一個服務刷新數據的時候,它會把這個消息放入到MQ的topic中,這樣其他監聽同一個topic的服務器都能得到通知,然後去更新自身的配置。這個topic默認是springCloudBus。

6、上面是通過刷新ConfigServer這一臺服務的端口,實現全部的ConfigClient數據同步,那如何做,可以只同步某一臺客戶端ConfigClient服務的數據呢?

還是刷新ConfigServer這一臺服務端口,但是後面需要加參數destination,指定需要更新的服務或實例,命令如下:

<code>destination/<code>

比如只刷新cloud-config-client:3355服務:

curl -X POST "http://localhost:3344/actuator/bus-refresh/cloud-config-client:3355"

這個名稱取自application.yml中的微服務名稱:spring: application: name: cloud-config-client,再加上端口號。

執行命令後,就實現了只更新某一臺服務的數據。

作者:楊33,北京互聯網公司在職Java開發,專注分享寫作乾貨。歡迎關注我,期待你的點贊評論。