溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

什么是服務(wù)發(fā)現(xiàn)以及Redis作為服務(wù)中介的介紹

發(fā)布時(shí)間:2021-09-04 11:26:22 來源:億速云 閱讀:140 作者:chen 欄目:大數(shù)據(jù)

本篇內(nèi)容主要講解“什么是服務(wù)發(fā)現(xiàn)以及Redis作為服務(wù)中介的介紹”,感興趣的朋友不妨來看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“什么是服務(wù)發(fā)現(xiàn)以及Redis作為服務(wù)中介的介紹”吧!

什么是服務(wù)發(fā)現(xiàn)?

服務(wù)發(fā)現(xiàn)并沒有怎樣的高深莫測(cè),它的原理再簡(jiǎn)單不過。

服務(wù)提供者是什么,簡(jiǎn)單點(diǎn)說就是一個(gè)HTTP服務(wù)器,提供了API服務(wù),有一個(gè)IP端口作為服務(wù)地址。服務(wù)消費(fèi)者是什么,它就是一個(gè)簡(jiǎn)單的進(jìn)程,想要訪問服務(wù)提供者提供的服務(wù)來干一些事情。一個(gè)HTTP服務(wù)器既可以是服務(wù)提供者對(duì)外提供服務(wù),也可以是消費(fèi)者需要?jiǎng)e的服務(wù)提供者提供的服務(wù),這就是服務(wù)依賴,沒有你我就不是我自己。復(fù)雜的服務(wù)甚至有多個(gè)服務(wù)依賴。

服務(wù)發(fā)現(xiàn)有三個(gè)角色,服務(wù)提供者、服務(wù)消費(fèi)者和服務(wù)中介。服務(wù)中介是聯(lián)系服務(wù)提供者和服務(wù)消費(fèi)者的橋梁。服務(wù)提供者將自己提供的服務(wù)地址注冊(cè)到服務(wù)中介,服務(wù)消費(fèi)者從服務(wù)中介那里查找自己想要的服務(wù)的地址,然后享受這個(gè)服務(wù)。服務(wù)中介提供多個(gè)服務(wù),每個(gè)服務(wù)對(duì)應(yīng)多個(gè)服務(wù)提供者。

什么是服務(wù)發(fā)現(xiàn)以及Redis作為服務(wù)中介的介紹

image

服務(wù)中介就是一個(gè)字典,字典里有很多key/value鍵值對(duì),key是服務(wù)名稱,value是服務(wù)提供者的地址列表。服務(wù)注冊(cè)就是調(diào)用字典的Put方法塞東西,服務(wù)查找就是調(diào)用字典的Get方法拿東西。

當(dāng)服務(wù)提供者節(jié)點(diǎn)掛掉時(shí),要求服務(wù)能夠及時(shí)取消注冊(cè),比便及時(shí)通知消費(fèi)者重新獲取服務(wù)地址。

當(dāng)服務(wù)提供者新加入時(shí),要求服務(wù)中介能及時(shí)告知服務(wù)消費(fèi)者,你要不要嘗試一下新的服務(wù)。

Redis作為服務(wù)中介

Redis里面有豐富的數(shù)據(jù)結(jié)構(gòu),拿來存儲(chǔ)服務(wù)字典再合適不過了。對(duì)每一個(gè)服務(wù)名稱,我們用一個(gè)set結(jié)構(gòu)存儲(chǔ)服務(wù)的IP:Port字符串。如果服務(wù)提供者加入,調(diào)用sadd命令加入服務(wù)地址,如果服務(wù)掛掉,調(diào)用srem命令移除服務(wù)地址。對(duì)服務(wù)消費(fèi)者使用smembers指令獲取所有服務(wù)地址然后在消費(fèi)進(jìn)程里隨機(jī)挑一個(gè),或者使用srandmemember指令直接獲取隨機(jī)服務(wù)地址。

這個(gè)時(shí)候你也許會(huì)表示懷疑,服務(wù)發(fā)現(xiàn)真這么簡(jiǎn)單么?答案是還差一點(diǎn),關(guān)于上面的這個(gè)解決方案有幾個(gè)問題。

第一個(gè)問題是服務(wù)提供者進(jìn)程如果被kill -9暴力殺死,不能主動(dòng)調(diào)用srem命令怎么辦?

這個(gè)時(shí)候服務(wù)列表中多了一個(gè)黑地址指向了不存在的服務(wù)而消費(fèi)者完全不知道,這個(gè)時(shí)候服務(wù)中介就成了黑中介了。那該怎么辦呢?

我們引入服務(wù)?;詈蜋z查機(jī)制,并更換數(shù)據(jù)結(jié)構(gòu)。服務(wù)提供者需要每隔5秒左右向服務(wù)中介匯報(bào)存活,服務(wù)中介將服務(wù)地址和匯報(bào)時(shí)間記錄在zset數(shù)據(jù)結(jié)構(gòu)的value和score中。服務(wù)中介需要每隔10秒左右檢查zset數(shù)據(jù)結(jié)構(gòu),踢掉匯報(bào)時(shí)間嚴(yán)重落后的服務(wù)地址項(xiàng)。這樣就可以準(zhǔn)實(shí)時(shí)地保證服務(wù)列表中服務(wù)地址的有效性。

第二個(gè)問題是服務(wù)列表變動(dòng)時(shí)如何通知消費(fèi)者。有兩種解決方案。

第一種是輪詢,消費(fèi)者需要每隔幾秒查詢服務(wù)列表是否有改變。如果服務(wù)很多,服務(wù)列表很大,消費(fèi)者很多,redis會(huì)有一定壓力。所以這時(shí)候可以引入服務(wù)列表的版本號(hào)機(jī)制,給每個(gè)服務(wù)提供一個(gè)key/value設(shè)置服務(wù)的版本號(hào),就是在服務(wù)列表發(fā)生變動(dòng)時(shí),遞增這個(gè)版本號(hào)。消費(fèi)者只需要輪詢這個(gè)版本號(hào)的變動(dòng)即可知道服務(wù)列表是否發(fā)生了變化。因?yàn)榉?wù)列表比較穩(wěn)定,僅在網(wǎng)絡(luò)嚴(yán)重抖動(dòng)的情況下才會(huì)頻繁發(fā)生變動(dòng),所以redis幾乎沒有壓力。

第二種是采用pubsub。這種方式及時(shí)性要明顯好于輪詢。缺點(diǎn)是每個(gè)pubsub都會(huì)占用消費(fèi)者一個(gè)線程和一個(gè)額外的redis連接。為了減少對(duì)線程和連接的浪費(fèi),我們使用單個(gè)pubsub廣播全局版本號(hào)的變動(dòng)。所謂全局版本號(hào)就是任意服務(wù)列表發(fā)生了變動(dòng),這個(gè)版本號(hào)都會(huì)遞增。接收到版本變動(dòng)的消費(fèi)者再去檢查各自的依賴服務(wù)列表的版本號(hào)是否發(fā)生了變動(dòng)。這種全局版本號(hào)也可以用于第一種輪詢方案。

第三個(gè)問題是redis是單點(diǎn)的,如果掛掉了怎么辦?

這是個(gè)大問題。正是因?yàn)檫@個(gè)問題的存在,流行的服務(wù)發(fā)現(xiàn)系統(tǒng)都是使用分布式數(shù)據(jù)庫zookeeper/etcd/consul等來作為服務(wù)中介,它們是分布式的多節(jié)點(diǎn)的,掛掉了一個(gè)節(jié)點(diǎn)沒關(guān)系,系統(tǒng)仍然可以正常工作。

什么是服務(wù)發(fā)現(xiàn)以及Redis作為服務(wù)中介的介紹

image

那如果整個(gè)zk集群掛掉會(huì)怎樣呢?其實(shí)每個(gè)服務(wù)消費(fèi)者在本地內(nèi)存里都會(huì)存一份當(dāng)前的服務(wù)列表,即使服務(wù)中介集群掛掉,也是可以使用當(dāng)前的服務(wù)列表正常工作的。

那redis作為服務(wù)中介就真的不靠譜了么?其實(shí)還有個(gè)redis-sentinel可以消除redis的單點(diǎn)問題,redis-sentinel可以在主節(jié)點(diǎn)掛掉的時(shí)候,自動(dòng)升級(jí)從節(jié)點(diǎn)為主節(jié)點(diǎn)。所以拿redis干這件事也是可以的。用redis干服務(wù)發(fā)現(xiàn)確實(shí)非常簡(jiǎn)單,雖然這種方式非常不流行。

服務(wù)提供者不只是HTTP服務(wù)

上面提到服務(wù)提供者簡(jiǎn)單來說就是HTTP服務(wù)器,其實(shí)服務(wù)多種多樣??梢允菙?shù)據(jù)庫服務(wù),可以是RPC服務(wù),可以是UDP服務(wù)等等。

如果是MySQL數(shù)據(jù)庫,那如何將MySQL服務(wù)注冊(cè)到服務(wù)中介呢?原生的MySQL可沒有提供這樣功能。一般做法是提供一個(gè)Agent代理去注冊(cè)。這個(gè)代理除了將服務(wù)地址注冊(cè)到服務(wù)中介外,還需要監(jiān)控MySQL的健康狀況,以便當(dāng)MySQL宕機(jī)時(shí)能及時(shí)切換到新的MySQL服務(wù)地址。一般這個(gè)Agent為了節(jié)省資源而不止監(jiān)控一個(gè)數(shù)據(jù)庫,它可以同時(shí)監(jiān)控多個(gè)數(shù)據(jù)庫,甚至是多種數(shù)據(jù)庫。

服務(wù)配置重加載

服務(wù)發(fā)現(xiàn)一般只是用來注冊(cè)和查找服務(wù)列表這樣一個(gè)比較單純的功能。不過現(xiàn)代的服務(wù)發(fā)現(xiàn)系統(tǒng)還會(huì)集成服務(wù)配置管理功能。這樣可以實(shí)現(xiàn)服務(wù)配置的實(shí)時(shí)重加載。原理也很簡(jiǎn)單,就是對(duì)于每一個(gè)服務(wù)項(xiàng),服務(wù)中介還會(huì)存儲(chǔ)一個(gè)單獨(dú)的key/value用來存儲(chǔ)這個(gè)服務(wù)的配置信息。當(dāng)這個(gè)配置項(xiàng)在后臺(tái)被修改時(shí),服務(wù)中介會(huì)實(shí)時(shí)通知相關(guān)服務(wù)器變更配置信息。比如數(shù)據(jù)庫地址變動(dòng),業(yè)務(wù)參數(shù)修改等。

服務(wù)管理后臺(tái)

為了便于服務(wù)管理,一般服務(wù)發(fā)現(xiàn)還會(huì)提供一個(gè)服務(wù)管理后臺(tái),用于管理人員查看服務(wù)集群的狀態(tài)。如果服務(wù)注冊(cè)和匯報(bào)時(shí)提供冗余的配置信息,服務(wù)管理后臺(tái)就可以呈現(xiàn)更為詳細(xì)的服務(wù)信息。服務(wù)管理后臺(tái)還可以將所有的服務(wù)依賴組織起來,呈現(xiàn)出一顆漂亮的服務(wù)依賴樹。

服務(wù)發(fā)現(xiàn)的一個(gè)簡(jiǎn)單實(shí)現(xiàn)

小編在閑暇之余基于Redis實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的服務(wù)發(fā)現(xiàn)系統(tǒng)Captain。讀者可以去github上下載這個(gè)項(xiàng)目進(jìn)行學(xué)習(xí)。我除了編寫了服務(wù)發(fā)現(xiàn)的服務(wù)器之外,客戶端sdk也一塊做了開發(fā),可能不太穩(wěn)定,希望讀者體諒,不要用于線上的業(yè)務(wù)系統(tǒng)。

什么是服務(wù)發(fā)現(xiàn)以及Redis作為服務(wù)中介的介紹

在Captain這個(gè)項(xiàng)目里,我的服務(wù)發(fā)現(xiàn)服務(wù)器將Redis提供的服務(wù)做了一層封裝,對(duì)外提供HTTP API進(jìn)行服務(wù)的注冊(cè)和查找,沒有使用上文提到的pubsub功能。

到此,相信大家對(duì)“什么是服務(wù)發(fā)現(xiàn)以及Redis作為服務(wù)中介的介紹”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI