簡(jiǎn)介
在上篇文章《微服務(wù)之配置中心》中寫到,客戶端可從服務(wù)端獲取配置信息,當(dāng)Git倉(cāng)庫(kù)中的配置文件修改后,為了讓客戶端獲取最新的配置信息站刑,可以通過執(zhí)行refresh操作進(jìn)行手動(dòng)刷新。但是這樣有問題鼻百,當(dāng)客戶端很多時(shí)(隨之系統(tǒng)的不斷擴(kuò)大)绞旅,如果需要每個(gè)客戶端都執(zhí)行一遍,那就蛋疼了温艇,顯然這種方案就不適合了玻靡。Spring Cloud作為微服務(wù)架構(gòu)的一個(gè)綜合解決方案,也提供了對(duì)應(yīng)的解決方案Spring Cloud Bus中贝,即消息總線囤捻。
這里要理解一個(gè)概念,消息總線邻寿。簡(jiǎn)單理解就是一個(gè)消息中心蝎土,眾多微服務(wù)實(shí)例可以連接到總線上,實(shí)例可以往消息中心發(fā)送或接收信息(通過監(jiān)聽)绣否。比如:實(shí)例A發(fā)送一條消息到總線上誊涯,總線上的實(shí)例B可以接收到信息(實(shí)例B訂閱了實(shí)例A),這樣的話蒜撮,消息總線就充當(dāng)一個(gè)中間者的角色暴构,使得實(shí)例A和實(shí)例B解偶了跪呈,很方便。
消息總線(Spring Cloud Bus)
原理
Spring Cloud Bus通過建立多個(gè)應(yīng)用之間的通信頻道取逾,管理和傳播應(yīng)用間的消息耗绿,從技術(shù)角度來(lái)說(shuō),應(yīng)用了AMQP消息代理作為通道砾隅,通過MQ的廣播機(jī)制實(shí)現(xiàn)消息的發(fā)送和接收误阻。以其典型應(yīng)用——配置中心客戶端刷新為例,說(shuō)明下工作流程:
(1)修改配置文件晴埂,觸發(fā)webhook向clientA發(fā)送bus/refresh究反;
(2)clientA重新從配置中心獲取新的配置信息,同時(shí)發(fā)送消息到Spring Cloud Bus儒洛;
(3)Spring Cloud Bus收到消息精耐,同時(shí)通知clientB、clientC(訂閱配置更新事件)琅锻;
(4)clientB卦停、clientC收到通知,重新請(qǐng)求配置中心浅浮,獲取新的配置信息。
這樣捷枯,三個(gè)客戶端均得到最新的配置滚秩。
消息代理
這個(gè)過程中,作為通道的AMQP消息代理很重要淮捆。AMQP(高級(jí)消息隊(duì)列協(xié)議郁油,是一個(gè)標(biāo)準(zhǔn))是一個(gè)網(wǎng)絡(luò)協(xié)議,從扮演角色來(lái)說(shuō)攀痊,消息代理從生產(chǎn)者(producers)那兒接收消息桐腌,并根據(jù)既定的路由規(guī)則把接收到的消息發(fā)送給處理消息的消費(fèi)者(consumers),這個(gè)過程中的發(fā)布者,消費(fèi)者苟径,消息代理可以存在于不同的設(shè)備上案站,下面簡(jiǎn)單介紹下工作流程(其實(shí)跟上面的類似):
消息(message)被發(fā)布者(publisher)發(fā)送給交換機(jī)(exchange),交換機(jī)常常被比喻成郵局或者郵箱棘街。然后交換機(jī)將收到的消息根據(jù)路由規(guī)則分發(fā)給綁定的隊(duì)列(queue)蟆盐。最后AMQP代理會(huì)將消息投遞給訂閱了此隊(duì)列的消費(fèi)者,或者消費(fèi)者按照需求自行獲取遭殉。
? ? ? AMQP作為一個(gè)標(biāo)準(zhǔn)協(xié)議石挂,主要實(shí)現(xiàn)方案有RabbitMQ、ActiveMQ险污、Qpid等痹愚。這里我主要以RabbitMQ為例進(jìn)行說(shuō)明,它是一個(gè)優(yōu)秀的微服務(wù)架構(gòu)消息中間件,與Spring Cloud Bus能夠很好的結(jié)合使用拯腮。
下圖顯示了RabbitMQ的Web管理首頁(yè):
(1)Broker:消息隊(duì)列服務(wù)器窖式,即負(fù)責(zé)接收生產(chǎn)者消息,發(fā)送至消費(fèi)者的疾瓮;
(2)Connections:連接脖镀,即發(fā)送者、消息接收者狼电、消費(fèi)者之間的物理連接蜒灰;
(3)Channel:通道,連接生產(chǎn)者肩碟、消費(fèi)者的邏輯結(jié)構(gòu)强窖。一個(gè)Connection可以對(duì)應(yīng)多個(gè)Channel;
(4)Exchange:消息交換機(jī)削祈,消息第一個(gè)到達(dá)的地方翅溺,可以指定路由規(guī)則,決定消息分發(fā)到不同的消息隊(duì)列中去髓抑;
(5)Queue:消息隊(duì)列咙崎,消息經(jīng)Exchange路由轉(zhuǎn)發(fā)至此,進(jìn)入邏輯等待狀態(tài)(等待消費(fèi)吨拍,即客戶端獲韧拭汀);
(6)Binding:綁定羹饰,把Exchange和Queue按照路由規(guī)則進(jìn)行綁定伊滋,即決定Exchange接收消息后,需要發(fā)送到哪些Queue中:
消息發(fā)送-接收原理圖
配置步驟
Config Server服務(wù)端
(1)在Config Server添加RabbitMQ依賴队秩,非常簡(jiǎn)單:
(2)修改配置文件笑旺,添加RabbitMQ的配置信息:
(3)啟動(dòng)類加注解:
Config Client客戶端
(1)在Config Client添加RabbitMQ依賴,非常簡(jiǎn)單:
(2)修改配置文件馍资,添加RabbitMQ的配置信息:
Eureka Server注冊(cè)中心
省略筒主。
測(cè)試
(1)啟動(dòng)Eureka Server注冊(cè)中心、ConfigServer服務(wù)端鸟蟹、Config Client客戶端(開啟兩個(gè)實(shí)例)物舒,如圖:
(2)客戶端獲取配置文件的值,如圖:
(3)修改配置文件值戏锹,改為apps.caac.net/demo冠胯,如圖:
(4)通過curl執(zhí)行刷新操作(配置服務(wù)端執(zhí)行/bus/refresh),如圖:
(5)客戶端重新獲取配置文件的值锦针,可知已獲取最新配置信息荠察,如圖:
(6)至此完成配置自動(dòng)刷新置蜀,當(dāng)部署正式環(huán)境時(shí),可以在配置文件修改時(shí)自動(dòng)執(zhí)行一個(gè)操作:curl -X POST http://localhost:8889/bus/refresh悉盆,在碼云后臺(tái)可以進(jìn)行設(shè)置(這里測(cè)試環(huán)境盯荤,設(shè)置不了,必須是公網(wǎng)地址)焕盟,如圖:
局部刷新
有時(shí)我們只想刷新部分微服務(wù)的配置秋秤,此時(shí)可通過/bus/refresh端點(diǎn)的destination參數(shù)來(lái)定位要刷新的應(yīng)用程序。
刷新指定實(shí)例(某一服務(wù))
執(zhí)行:/bus/refresh?destination=customers:9000脚翘,
其中灼卢,customers:9000指的是各個(gè)微服務(wù)的ApplicationContext ID(默認(rèn)為:${spring.application.name}:${server.port})。
刷新全部實(shí)例(某一服務(wù))
執(zhí)行:/bus/refresh?destination=customers:**来农,這樣就可以觸發(fā)customers微服務(wù)所有實(shí)例的配置刷新鞋真。
注意:這里的${spring.application.name}區(qū)分大小寫。