服務(wù)發(fā)現(xiàn)

參考
老錢 服務(wù)發(fā)現(xiàn)的基本原理
服務(wù)發(fā)現(xiàn)
聊聊 Node.js RPC(二)— 服務(wù)發(fā)現(xiàn)

在傳統(tǒng)的系統(tǒng)部署中,服務(wù)運(yùn)行在一個(gè)固定的已知的 IP 和端口上绸贡,如果一個(gè)服務(wù)需要調(diào)用另外一個(gè)服務(wù)免猾,可以通過地址直接調(diào)用,但是吏夯,在虛擬化或容器話的環(huán)境中静浴,服務(wù)實(shí)例的啟動和銷毀是很頻繁的磷籍,服務(wù)地址在動態(tài)的變化适荣。服務(wù)發(fā)現(xiàn)的主要優(yōu)點(diǎn)是可以無需了解架構(gòu)的部署拓?fù)洵h(huán)境,只通過服務(wù)的名字就能夠使用服務(wù)院领,提供了一種服務(wù)發(fā)布與查找的協(xié)調(diào)機(jī)制弛矛。服務(wù)發(fā)現(xiàn)除了提供服務(wù)注冊、目錄和查找三大關(guān)鍵特性比然,還需要能夠提供健康監(jiān)控丈氓、多種查詢、實(shí)時(shí)更新和高可用性等强法。

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

服務(wù)發(fā)現(xiàn)并沒有怎樣的高深莫測饮怯,它的原理再簡單不過闰歪。只是市面上太多文章將服務(wù)發(fā)現(xiàn)的難度妖魔化,讀者被繞的云里霧里蓖墅,頓覺自己智商低下不敢高攀库倘。

  • 服務(wù)提供者是什么临扮,簡單點(diǎn)說就是一個(gè)HTTP服務(wù)器,提供了API服務(wù)教翩,有一個(gè)IP端口作為服務(wù)地址杆勇。
  • 服務(wù)消費(fèi)者是什么,它就是一個(gè)簡單的進(jìn)程饱亿,想要訪問服務(wù)提供者提供的服務(wù)來干一些事情蚜退。一個(gè)HTTP服務(wù)器既可以是服務(wù)提供者對外提供服務(wù),也可以是消費(fèi)者需要別的服務(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ù)地址注冊到服務(wù)中介之宿,服務(wù)消費(fèi)者從服務(wù)中介那里查找自己想要的服務(wù)的地址郭脂,然后享受這個(gè)服務(wù)钾军。服務(wù)中介提供多個(gè)服務(wù),每個(gè)服務(wù)對應(yīng)多個(gè)服務(wù)提供者系忙。
image.png

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

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

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

二、Redis作為服務(wù)中介

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

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

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

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

我們引入服務(wù)笨莘遥活和檢查機(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ù)地址的有效性最楷。

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

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

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

3.第三個(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)仍然可以正常工作廉侧。


image.png

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

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

三潜腻、服務(wù)提供者不只是HTTP服務(wù)

上面提到服務(wù)提供者簡單來說就是HTTP服務(wù)器,其實(shí)服務(wù)多種多樣器仗∪诨粒可以是數(shù)據(jù)庫服務(wù),可以是RPC服務(wù)精钮,可以是UDP服務(wù)等等威鹿。

如果是MySQL數(shù)據(jù)庫,那如何將MySQL服務(wù)注冊到服務(wù)中介呢轨香?原生的MySQL可沒有提供這樣功能忽你。一般做法是提供一個(gè)Agent代理去注冊。這個(gè)代理除了將服務(wù)地址注冊到服務(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)一般只是用來注冊和查找服務(wù)列表這樣一個(gè)比較單純的功能蚌堵。不過現(xiàn)代的服務(wù)發(fā)現(xiàn)系統(tǒng)還會集成服務(wù)配置管理功能买决。這樣可以實(shí)現(xiàn)服務(wù)配置的實(shí)時(shí)重加載。原理也很簡單吼畏,就是對于每一個(gè)服務(wù)項(xiàng)督赤,服務(wù)中介還會存儲一個(gè)單獨(dú)的key/value用來存儲這個(gè)服務(wù)的配置信息。當(dāng)這個(gè)配置項(xiàng)在后臺被修改時(shí)泻蚊,服務(wù)中介會實(shí)時(shí)通知相關(guān)服務(wù)器變更配置信息躲舌。比如數(shù)據(jù)庫地址變動,業(yè)務(wù)參數(shù)修改等性雄。

五没卸、服務(wù)管理后臺

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

六细卧、兩種主要的服務(wù)發(fā)現(xiàn)方式
1.客戶端服務(wù)發(fā)現(xiàn)
image.png

在使用客戶端發(fā)現(xiàn)方式時(shí)尉桩,客戶端通過查詢服務(wù)注冊中心,獲取可用的服務(wù)的實(shí)際網(wǎng)絡(luò)地址(IP 和端口)贪庙。然后通過負(fù)載均衡算法來選擇一個(gè)可用的服務(wù)實(shí)例蜘犁,并將請求發(fā)送至該服務(wù)。優(yōu)點(diǎn):架構(gòu)簡單止邮,擴(kuò)展靈活这橙,方便實(shí)現(xiàn)負(fù)載均衡功能,缺點(diǎn):強(qiáng)耦合农尖,有一定開發(fā)成本析恋。

2.服務(wù)端服務(wù)發(fā)現(xiàn)
image.png

客戶端向load balancer 發(fā)送請求。load balancer 查詢服務(wù)注冊中心找到可用的服務(wù)盛卡,然后轉(zhuǎn)發(fā)請求到該服務(wù)上助隧。和客戶端發(fā)現(xiàn)一樣,服務(wù)都要到注冊中心進(jìn)行服務(wù)注冊和注銷。優(yōu)點(diǎn):服務(wù)的發(fā)現(xiàn)邏輯對客戶端是透明的并村。缺點(diǎn):需要額外部署和維護(hù)高可用的負(fù)載均衡器巍实。

3.服務(wù)發(fā)現(xiàn)和負(fù)載均衡的關(guān)系

最后提到負(fù)載均衡這個(gè)概念是為后面文章做鋪墊,因?yàn)樗苋菀缀头?wù)發(fā)現(xiàn)混淆哩牍,在很多簡單的場景我們甚至也不去刻意區(qū)分它們棚潦。但本質(zhì)上它們的層次和解決的問題是不一樣的,簡單說服務(wù)發(fā)現(xiàn)是負(fù)載均衡的前提膝昆,負(fù)載均衡要解決的是拿到服務(wù)列表后將流量合理的分配到各個(gè)節(jié)點(diǎn)上的問題丸边。

七、常見的服務(wù)發(fā)現(xiàn)框架

常見服務(wù)發(fā)現(xiàn)框架 Consul荚孵、 ZooKeeper以及Etcd

ZooKeeper 是這種類型的項(xiàng)目中歷史最悠久的之一妹窖,它起源于 Hadoop。它非常成熟收叶、可靠骄呼,被許多大公司(YouTube、eBay判没、雅虎等)使用蜓萄。

Etcd是一個(gè)采用 HTTP 協(xié)議的健/值對存儲系統(tǒng),它是一個(gè)分布式和功能層次配置系統(tǒng)澄峰,可用于構(gòu)建服務(wù)發(fā)現(xiàn)系統(tǒng)嫉沽。其很容易部署、安裝和使用摊阀,提供了可靠的數(shù)據(jù)持久化特性耻蛇。搭配一些第三方工具,etcd(健/值對存儲系統(tǒng))+ Registrator(服務(wù)注冊器) + Confd(輕量級的配置管理工具)

Consul 是強(qiáng)一致性的數(shù)據(jù)存儲胞此,使用 Gossip 形成動態(tài)集群。它提供分級鍵/值存儲方式跃捣,不僅可以存儲數(shù)據(jù)漱牵,而且可以用于注冊器件事各種任務(wù),從發(fā)送數(shù)據(jù)改變通知到運(yùn)行健康檢查和自定義命令

image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末疚漆,一起剝皮案震驚了整個(gè)濱河市酣胀,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌娶聘,老刑警劉巖闻镶,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異丸升,居然都是意外死亡铆农,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進(jìn)店門狡耻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來墩剖,“玉大人猴凹,你說我怎么就攤上這事×朐恚” “怎么了郊霎?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長爷绘。 經(jīng)常有香客問我书劝,道長,這世上最難降的妖魔是什么土至? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任庄撮,我火速辦了婚禮,結(jié)果婚禮上毙籽,老公的妹妹穿的比我還像新娘洞斯。我一直安慰自己,他們只是感情好坑赡,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布烙如。 她就那樣靜靜地躺著,像睡著了一般毅否。 火紅的嫁衣襯著肌膚如雪亚铁。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天螟加,我揣著相機(jī)與錄音徘溢,去河邊找鬼。 笑死捆探,一個(gè)胖子當(dāng)著我的面吹牛然爆,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播黍图,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼曾雕,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了助被?” 一聲冷哼從身側(cè)響起剖张,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎揩环,沒想到半個(gè)月后搔弄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡丰滑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年顾犹,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,133評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蹦渣,死狀恐怖哄芜,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情柬唯,我是刑警寧澤认臊,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站锄奢,受9級特大地震影響失晴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜拘央,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一涂屁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧灰伟,春花似錦拆又、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至挡爵,卻和暖如春竖般,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背茶鹃。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工涣雕, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人闭翩。 一個(gè)月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓挣郭,卻偏偏與公主長得像,于是被迫代替她去往敵國和親男杈。 傳聞我的和親對象是個(gè)殘疾皇子丈屹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評論 2 355

推薦閱讀更多精彩內(nèi)容