接上篇《39.Spring Cloud Config配置屬性刷新之手動刷新》 Spring Cloud版本爲Finchley.SR2版
上兩篇我們講解了有關Spring Cloud Config配置的手動刷新機制,本篇我們來講解如何實現Spring Cloud Config配置屬性的自動刷新功能。
本部分官方文檔:https://cloud.spring.io/spring-cloud-static/Finchley.SR4/single/spring-cloud.html#_push_notifications_and_spring_cloud_bus
注:好像Finchley.SR2的文檔已經掛了,最新的是Finchley.SR4的文檔。
上一章我們講解我如何進行Config屬性的手動刷新操作(使用refresh端點),但是也分析了手動刷新的一些弊端,例如集羣情況下,手動刷新所有節點的效率太低。所以我們需要一個自動刷新的策略,來實現當遠端配置更新後,系統可以批量更新所有客戶端配置信息的效果。
其實批量自動刷新的策略很簡答,即在Config客戶端集羣之間架設一箇中間件,當其中一個Config客戶端調用refresh服務進行遠程倉庫配置更新時,該更新操作會推動至中間件,其它連接了該中間件的Config客戶端,感知到中間件的消息變化,也會同時進行配置的refresh更新,從而實現一步操作,整個Config客戶端集羣自動刷新的效果。具體如何操作呢?用什麼中間件呢?且看下文一一道來。
一、Spring Cloud自動刷新策略
在Spring Cloud的官方文檔中,有“Push Notifications and Spring Cloud Bus”的一章,其意思大致是“推送消息和Spring Cloud Bus”。大家一提到“推送消息”應該就會想到常用的消息中間件MQ(例如ActiveMQ,RabbitMQ,Kafka、RocketMQ等),一般MQ就是存儲一個消息隊列,生產消息的生產者進行消息信息的生產,消費者進行消息信息的消費。
注:想詳細瞭解MQ相關基礎知識,請閱讀我的【RabbitMQ消息中間件】專欄:
專欄地址:https://blog.csdn.net/u013517797/category_9276117.html
而其中的“Spring Cloud Bus”,是Spring Cloud的一個子項目,它基於AMQP協議(高級消息隊列協議,用於消息的生產和消費),我們可以使用RabbitMQ或Kafka來實現一個基本的基於AMQP協議的應用,來支持消息中間件的接入。
以上就是Spring Cloud自動刷新的策略,我們只需要架設好消息中間件,編寫好屬性服務端和遠端倉庫之間的連接,即可實現自動刷新,那麼開始吧。
二、下載安裝消息中間件
我們這裏使用RabbitMQ的消息中間件,我們先來下載和配置它。
由於之前我已經寫有相關的博客專欄了,這裏我就不在贅述,需要了解安裝和配置詳情的小夥伴,請移步至下面的博文連接:
【RabbitMQ消息中間件】2.安裝RabbitMQ:https://blog.csdn.net/acmman/article/details/79371312
我們這裏下載了RabbitMQ 3.8.4的windows版本:
配置好環境變量等參數後,在RabbitMQ文件目錄的“sbin”文件夾下執行相關的指令(具體參見上面“安裝RabbitMQ”的博文連接)。
注:常用指令:
rabbitmq-plugins enable rabbitmq_management 開啓插件
rabbitmq-service remove 移除服務
rabbitmq-service install 安裝服務
rabbitmq-service start 或者 net start rabbitmq 啓動服務
rabbitmq-service stop 或者 net stop rabbitmq 停止服務
rabbitmqctl status 查看服務狀態
rabbitmq-server restart 重啓服務
啓動完相關服務後,我們瀏覽器中輸入地址http://127.0.0.1:15672/查看,就可以看到RabbitMQ的Web管理頁面:
Web管理頁面的功能介紹詳見下面的博文鏈接:
【RabbitMQ消息中間件】3.管理界面中的功能:https://blog.csdn.net/acmman/article/details/79438143
這裏我們就安裝好了MQ消息中間件了,接下來我們就要使用Spring Cloud Bus來實現配置的批量刷新了。
三、客戶端整合Spring Cloud Bus並測試
我們拷貝原來的microserver-config-client-refresh工程進行修改,創建一個microserver-config-client-refresh-bus工程:
其中,pom.xml中引入spring-cloud-starter-bus-amqp的依賴,用於連接RabbitMQ:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>microserver-config-client-refresh-bus</artifactId>
<name>microserver-config-client-refresh-bus</name>
<parent>
<groupId>com.microserver.cloud</groupId>
<artifactId>microserver-spring-cloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- spring-cloud-starter-bus-amqp -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
</dependencies>
</project>
然後修改bootstrap.yml配置文件,添加連接RabbitMQ的配置:
spring:
cloud:
config:
uri: http://localhost:8090
username: user
password: password123
profile: dev
label: master #如果ConfigServer的後端存儲是Git,默認就爲master
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
這裏RabbitMQ的默認管理賬號和密碼都是guest。
Spring Cloud Bus提供了一個批量刷新的端點“bus/refresh”,來實現刷新本服務的同時,將刷新動作推送至消息中間件,通知其它連接了消息中間件的客戶端進行自動刷新操作。
注:spring boot2.0之前,是通過訪問“bus/refresh”來實現批量刷新的,但是spring boot2.0之後,/bus/refresh全部整合到actuator裏面了,所以之前1.x的management.security.enabled全部失效,不適用於2.0,訪問路徑變爲“actuator/bus-refresh”,所以必須在actuator配置端點中暴露“bus-refresh”節點,這裏在application.yml中的include配置下增加bus-refresh:
server:
port: 8092
spring:
application:
name: microserver-config-client
management:
endpoints:
web:
exposure:
include: refresh,bus-refresh
type: abcd
然後我們分別啓動Config Server和兩個我們上面新建的Config Client(一個端口爲8091,一個端口爲8092):
我們觀察microserver-config-client-refresh-bus的控制檯,可以看到已經連接上了MQ:
再看上面的端點加載環節,加載了bus-refresh的刷新端點:
此時我們訪問兩個客戶端的“profileType”節點,都是“client-dev-refresh”:
此時我們修改本地倉庫中的microserver-config-client-dev.yml文件,將原來的“client-dev-refresh”修改爲“client-dev-refresh-bus”,然後提交至遠程倉庫:
然後我們使用“actuator/bus-refresh”來進行批量刷新測試,這裏用postman訪問端口爲8091的客戶端的“actuator/bus-refresh”服務:
此時我們再刷新8091和8092的“profileType”節點,發現遠端倉庫的更新,被同步過來了:
消息中間件的作用,使得某個客戶端進行刷新,可以促使整個客戶端集羣全部刷新的效果。
四、自動批量刷新的原理
上面我們使用Bus實現了客戶端批量自動刷新配置的效果,那麼它的原理是什麼呢?
首先,我訪問的“actuator/bus-refresh”節點,它觸發了一個事件,該事件傳播到了其它的節點,其它節點獲取事件後,也進行了刷新的效果。
我們重新在8091執行一下“actuator/bus-refresh”節點,可以看一下RabbitMQ的控制檯的Queues模塊,找到我們的消息隊列,可以看到刷新事件被推送到了該隊列中:
然後可以看到,過了幾秒後,該消息事件就被8092消費了:
8092得到信息後,也進行了配置刷新的操作。
以上就是自動批量刷新的基本原理,在深入學習了RabbitMQ的相關消息模式後,會更加理解該原理。
五、絕對的全自動刷新
我們上面只是實現了半自動刷新的效果,即我們還需要手動調用“actuator/bus-refresh”節點。要想實現全自動刷新,我們還需要做一些操作。
自動刷新的機制,我們需要藉助遠程倉庫裏的“WebHooks”功能來實現。所謂的“WebHooks”,明面上翻譯是“Web鉤子函數”,所謂的“Web鉤子函數”函數,即是在Web程序上執行了一個操作後,可以反向向遠程服務發送一個請求,以此來實現一些操作。
這裏我們使用的是碼雲,我們打開之前設置的遠端倉庫,選擇“WebHooks”:
我們可以看到,上面有一個關於“WebHooks”的說明,即“每次您 push 代碼後,都會給遠程 HTTP URL 發送一個 POST 請求”,這裏聰明的小夥伴可能已經想到了,在push之後,配置8091的“actuator/bus-refresh”節點作爲遠端調用的POST請求路徑,這樣不就可以實現全自動刷新了嗎?沒錯,大致的配置如下:
當然,我們的服務是跑在本地的,這裏的localhost地址在gitee上是無法訪問的,這裏就沒有辦法進行測試了,如果有公網映射的小夥伴,可以試驗一下,或者使用如花生殼之類的有公網映射服務的軟件來暴露出一個公網地址,在這裏我就不展開了。
以上就是實現pring Cloud Config配置自動刷新效果的全部內容。
下一篇我們來深入講解一下上面使用的Spring Cloud Bus的插件,如何優化Config的配置和刷新。
參考:《51CTO學院Spring Cloud高級視頻》
轉載請註明出處:https://blog.csdn.net/acmman/article/details/106440320