自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

手繪了11張圖,幫你看明白 Zookeeper 如何實(shí)現(xiàn)服務(wù)注冊(cè)發(fā)現(xiàn)

大數(shù)據(jù) Hadoop
作為一個(gè)協(xié)調(diào)服務(wù),常常用來(lái)配合其他中間件來(lái)用,比如:Dubbo + Zookeeper,Hadoop + Zookeeper等,Zookeeper可以實(shí)現(xiàn):服務(wù)注冊(cè)發(fā)現(xiàn)、分布式鎖、配置中心等功能。今天我們重點(diǎn)來(lái)學(xué)習(xí)一下 Zookeeper 是如何實(shí)現(xiàn)服務(wù)注冊(cè)發(fā)現(xiàn)的。

對(duì)微服務(wù)稍有了解的小伙伴應(yīng)該都聽(tīng)說(shuō)過(guò) Zookeeper,我們來(lái)看看在官網(wǎng)上是如何介紹的:

Zookeeper 是一個(gè)分布式的、開(kāi)源的分布式應(yīng)用程序協(xié)調(diào)服務(wù)。

作為一個(gè)協(xié)調(diào)服務(wù),常常用來(lái)配合其他中間件來(lái)用,比如:Dubbo + Zookeeper,Hadoop + Zookeeper等,Zookeeper可以實(shí)現(xiàn):服務(wù)注冊(cè)發(fā)現(xiàn)、分布式鎖、配置中心等功能。

今天我們重點(diǎn)來(lái)學(xué)習(xí)一下 Zookeeper 是如何實(shí)現(xiàn)服務(wù)注冊(cè)發(fā)現(xiàn)的。

分布式帶來(lái)的問(wèn)題

先正式介紹 Zookeeper 之前,我們先引入一個(gè)業(yè)務(wù)場(chǎng)景:訂單服務(wù)需要調(diào)用用戶服務(wù)的接口。

要實(shí)現(xiàn)這個(gè)功能非常簡(jiǎn)單,我們只需要知道用戶服務(wù)的 ip 和 port 就可以了。

突然有一天,用戶數(shù)量激增,用戶服務(wù)扛不住了,這個(gè)時(shí)候只能進(jìn)行擴(kuò)容,多部署幾個(gè)實(shí)例,這個(gè)時(shí)候問(wèn)題就來(lái)了,訂單服務(wù)該調(diào)用哪個(gè)用戶服務(wù)的實(shí)例?

最簡(jiǎn)單的辦法就是在訂單服務(wù)中配置所有的用戶服務(wù)實(shí)例,然后使用某種算法(比如說(shuō)輪詢)從配置列表中選擇一個(gè)就可以了。

看似問(wèn)題解決了,其實(shí)隱患很大:

  • 用戶服務(wù)的實(shí)例數(shù)會(huì)根據(jù)負(fù)載進(jìn)行動(dòng)態(tài)調(diào)整,每次調(diào)整完都要更新配置列表,非常麻煩,也容易出錯(cuò)。
  • 某些服務(wù)實(shí)例 down 掉了,如果沒(méi)來(lái)得及從配置列表中清除掉,就會(huì)造成調(diào)用者請(qǐng)求接口報(bào)錯(cuò)。

如何解決呢?往往解決這類(lèi)分布式問(wèn)題都需要一塊公共的區(qū)域來(lái)保存這些信息。

用 Redis 解決

需要一塊公共的區(qū)域保存這些信息,那利用 Redis 是否可以實(shí)現(xiàn)?

每個(gè)服務(wù)實(shí)例啟動(dòng)之后都向 Redis 注冊(cè)信息,停止時(shí)也從 Redis 中刪除數(shù)據(jù)。

存放在 Redis 中的信息簡(jiǎn)單來(lái)說(shuō)就是服務(wù)實(shí)例的 ip + port,訂單服務(wù)需要調(diào)用用戶服務(wù)時(shí)直接從 Redis 中獲取即可。

簡(jiǎn)單流程如下圖所示:

每次調(diào)用的時(shí)候都去 Redis 查詢一次,頻繁的查詢可能會(huì)導(dǎo)致性能瓶頸,為了解決這個(gè)問(wèn)題我們可以在查詢之后在本地緩存一份數(shù)據(jù),這樣每次調(diào)用可以優(yōu)先從本地獲取數(shù)據(jù)。

但這樣又會(huì)出現(xiàn)新的問(wèn)題,本地緩存如何刷新呢,如果服務(wù)提供者某些實(shí)例 down 掉了或者擴(kuò)容新增了一批實(shí)例,那服務(wù)消費(fèi)者如何才能快速感知到呢?

要想解決這個(gè)問(wèn)題,最先想到的一個(gè)辦法就是讓服務(wù)消費(fèi)者定時(shí)輪詢 Redis,發(fā)現(xiàn)有更新了就去更新本地緩存,看起來(lái)也能解決本地緩存刷新的問(wèn)題,但是多久輪詢一次呢,1 秒或者10 秒?

輪詢時(shí)間太短依然有性能瓶頸問(wèn)題,這樣本地緩存也沒(méi)有存在的必要了;輪詢時(shí)間太長(zhǎng),本地緩存來(lái)不及更新,就會(huì)存在 "臟" 數(shù)據(jù)。

以上的方案都不完美,并且不優(yōu)雅,主要有以下幾點(diǎn):

基于定時(shí)任務(wù)會(huì)導(dǎo)致很多無(wú)效的查詢。

定時(shí)任務(wù)存在周期性,沒(méi)法做到實(shí)時(shí),這樣就可能存在請(qǐng)求異常。

如果服務(wù)被強(qiáng)行 kill,沒(méi)法及時(shí)清除 Redis,這樣這個(gè)看似可用的服務(wù)將永遠(yuǎn)不可用!

所以我們需要一個(gè)更加靠譜的解決方案。

用 Zookeeper 解決

用過(guò) Dubbo 的小伙伴對(duì)這張圖肯定很熟悉,步驟 0 到 4 是服務(wù)注冊(cè)發(fā)現(xiàn)的核心流程。

這個(gè)流程與我們上面討論的不謀而合,那 Dubbo 是如何實(shí)現(xiàn)的呢?實(shí)際上 Dubbo 作為一個(gè)通用的框架提供了多種解決方案,如:Zookeeper、Nacos等。

不管是哪種方案,總結(jié)起來(lái)都是一種套路,基本流程如下:

  • 每個(gè)服務(wù)實(shí)例啟動(dòng)之后將自己的信息(ip+port)寫(xiě)入公共區(qū)域;
  • 調(diào)用者訂閱自己感興趣的服務(wù)實(shí)例,獲取服務(wù)實(shí)例信息列表后緩存在自己本地;
  • 服務(wù)實(shí)例停止或者 down 調(diào)后將公共區(qū)域自己的信息清除掉;
  • 公共區(qū)域通知調(diào)用者你感興趣的信息已經(jīng)發(fā)生變更,請(qǐng)更新一下本地的緩存。

Zookeeper的重點(diǎn)特性

(1)樹(shù)狀目錄結(jié)構(gòu)

Zookeeper是一個(gè)樹(shù)狀的文件目錄結(jié)構(gòu),與 Unix 文件系統(tǒng)很類(lèi)似。樹(shù)中每個(gè)節(jié)點(diǎn)可以稱(chēng)作為一個(gè)ZNode,每一個(gè)ZNode都可以通過(guò)其路徑唯一標(biāo)識(shí),最重要的是我們可以對(duì)每個(gè) ZNode 進(jìn)行增刪改查。

(2)持久節(jié)點(diǎn)(Persistent)

客戶端與Zookeeper服務(wù)端斷開(kāi)連接后,節(jié)點(diǎn)仍然存在不會(huì)被刪除,這樣的節(jié)點(diǎn)就叫做持久節(jié)點(diǎn)。

(3)持久有序節(jié)點(diǎn)(Persistent_sequential)

持久有序節(jié)點(diǎn)是在上面持久節(jié)點(diǎn)的特性上加上了有序性,有序性的意思是服務(wù)向Zookeeper注冊(cè)信息時(shí),Zookeeper 根據(jù)注冊(cè)順序給每個(gè)節(jié)點(diǎn)編號(hào)。

(4)臨時(shí)節(jié)點(diǎn)(Ephemeral)

客戶端與Zookeeper服務(wù)端斷開(kāi)連接后,該節(jié)點(diǎn)被刪除。

注意:臨時(shí)節(jié)點(diǎn)下不存在子節(jié)點(diǎn);持久節(jié)點(diǎn)下可以存在臨時(shí)節(jié)點(diǎn)。

(5)臨時(shí)有序節(jié)點(diǎn)(Ephemeral_sequential)

臨時(shí)有序節(jié)點(diǎn)是在臨時(shí)節(jié)點(diǎn)的基礎(chǔ)上再加上有序性,跟持久有序節(jié)點(diǎn)類(lèi)似。

(6)節(jié)點(diǎn)監(jiān)聽(tīng)(Wacher)

節(jié)點(diǎn)監(jiān)聽(tīng)是Zookeeper最重要的特性之一,客戶端可以監(jiān)聽(tīng)任意節(jié)點(diǎn),節(jié)點(diǎn)有任何變化 Zookeeper 可以通過(guò)回調(diào)的方式通知給客戶端,這樣客戶端不用輪詢就可以及時(shí)感知節(jié)點(diǎn)變化。

如下圖所示,客戶端(client)開(kāi)始監(jiān)聽(tīng)臨時(shí)節(jié)點(diǎn) 1,因某種原因臨時(shí)節(jié)點(diǎn) 1 被刪除了,Zookeeper 通過(guò)回調(diào)將變化通知給 client 了。

Zookeeper 實(shí)現(xiàn)服務(wù)注冊(cè)發(fā)現(xiàn)

了解了Zookeeper的一些重要特性,我們?cè)賮?lái)看下 Zookeeper 是如何實(shí)現(xiàn)服務(wù)注冊(cè)和發(fā)現(xiàn)的。還是以訂單服務(wù)、用戶服務(wù)的場(chǎng)景為例。

服務(wù)提供方(用戶服務(wù))啟動(dòng)成功后將服務(wù)信息注冊(cè)到Zookeeper,服務(wù)信息包括實(shí)例的 ip、端口等元信息。注冊(cè)成功 Zookeeper 還可以通過(guò)心跳監(jiān)測(cè)來(lái)動(dòng)態(tài)感知實(shí)例變化,詳細(xì)的過(guò)程這里不展開(kāi)。

服務(wù)消費(fèi)方(訂單服務(wù))需要調(diào)用用戶服務(wù)的接口,但因?yàn)椴恢缹?shí)例的 ip、端口等信息,只能從 Zookeeper 中獲取調(diào)用地址列表,然后進(jìn)行調(diào)用,這個(gè)過(guò)程成為服務(wù)的訂閱。

訂閱成功后服務(wù)消費(fèi)方可以將調(diào)用列表緩存在本地,這樣不用每次都去調(diào)用 Zookeeper 獲取。一旦 Zookeeper感知到用戶服務(wù)實(shí)例變化后就會(huì)通知給服務(wù)消費(fèi)方,服務(wù)消費(fèi)方拿到結(jié)果后就會(huì)更新本地緩存,這個(gè)過(guò)程稱(chēng)之為通知。

服務(wù)注冊(cè)原理

服務(wù)啟動(dòng)后會(huì)自動(dòng)向 Zookeeper 注冊(cè),注冊(cè)的規(guī)則如下:

每個(gè)服務(wù)會(huì)創(chuàng)建一個(gè)持久節(jié)點(diǎn)和若干個(gè)臨時(shí)節(jié)點(diǎn)。比如:用戶服務(wù)首先創(chuàng)建一個(gè)持久節(jié)點(diǎn) user,然后每個(gè)服務(wù)實(shí)例會(huì)在持久節(jié)點(diǎn)下創(chuàng)建一個(gè)臨時(shí)有序節(jié)點(diǎn)。

服務(wù)動(dòng)態(tài)發(fā)現(xiàn)原理

由于訂單服務(wù)需要調(diào)用用戶服務(wù)的接口,所以訂單服務(wù)會(huì)訂閱 user 節(jié)點(diǎn),一旦用戶服務(wù)有變化(增加實(shí)例或者減少實(shí)例),Zookeeper 都會(huì)將最新的列表信息推送給訂單服務(wù),這個(gè)過(guò)程就是服務(wù)動(dòng)態(tài)發(fā)現(xiàn)的基本原理。少用文字描述,大家直接看圖:

小結(jié)

文章首先引入訂單服務(wù)和用戶服務(wù)的例子,說(shuō)明了分布式場(chǎng)景下可能存在的問(wèn)題:服務(wù)提供者實(shí)例越多,維護(hù)的成本越高。

經(jīng)過(guò)分析,我們得出結(jié)論:需要使用一塊公共的區(qū)域存儲(chǔ)實(shí)例信息。

如何提供公共的區(qū)域?我們先想到了Redis。

經(jīng)過(guò)實(shí)踐發(fā)現(xiàn) Redis 確實(shí)可以解決服務(wù)注冊(cè)和服務(wù)發(fā)現(xiàn)的問(wèn)題,但是同時(shí)又引入了其他問(wèn)題:

  • 基于定時(shí)任務(wù)會(huì)導(dǎo)致很多無(wú)效的查詢。
  • 定時(shí)任務(wù)存在周期性,沒(méi)法做到實(shí)時(shí),這樣就可能存在請(qǐng)求異常。
  • 如果服務(wù)被強(qiáng)行 kill,沒(méi)法及時(shí)清除 Redis,這樣這個(gè)看似可用的服務(wù)將永遠(yuǎn)不可用!

當(dāng)我們一籌莫展的時(shí)候,我們發(fā)現(xiàn)強(qiáng)大的 Dubbo 框架使用了 Zookeeper 來(lái)實(shí)現(xiàn)服務(wù)注冊(cè)和發(fā)現(xiàn)的功能。為了更好的學(xué)習(xí) Zookeeper 是如何實(shí)現(xiàn)服務(wù)注冊(cè)和發(fā)現(xiàn)功能的,我們了解到 Zookeeper 的一些重要特性:

  • 樹(shù)狀目錄結(jié)構(gòu)
  • 持久節(jié)點(diǎn)
  • 持久有序節(jié)點(diǎn)
  • 臨時(shí)節(jié)點(diǎn)
  • 臨時(shí)有序節(jié)點(diǎn)
  • 節(jié)點(diǎn)監(jiān)控

這些重要的特性為最后實(shí)現(xiàn)服務(wù)注冊(cè)和動(dòng)態(tài)發(fā)現(xiàn)打下了堅(jiān)實(shí)的基礎(chǔ)。

文章的最后,我們?cè)俅我杂唵畏?wù)和用戶服務(wù)為例通過(guò)兩張圖生動(dòng)的詮釋了服務(wù)注冊(cè)和動(dòng)態(tài)發(fā)現(xiàn)的流程和原理。


責(zé)任編輯:武曉燕 來(lái)源: 愛(ài)笑的架構(gòu)師
相關(guān)推薦

2022-03-07 17:43:30

注冊(cè)微服務(wù)架構(gòu)

2015-12-25 11:00:52

Zookeeper的Python

2021-02-07 09:01:10

Java并發(fā)編程

2020-11-02 12:50:29

分布式系統(tǒng)服務(wù)

2022-02-16 18:00:19

動(dòng)態(tài)代理代碼靜態(tài)代理

2023-04-26 01:17:16

惡意注冊(cè)Java驗(yàn)證

2022-04-26 05:36:42

服務(wù)治理模式

2022-08-16 18:52:20

分布式容錯(cuò)架構(gòu)

2024-12-27 00:37:46

2022-08-01 10:43:11

RocketMQZookeeper注冊(cè)中心

2022-02-07 07:10:32

服務(wù)注冊(cè)功能

2014-07-22 10:56:45

互聯(lián)網(wǎng)印度

2021-03-23 10:25:05

Redis數(shù)據(jù)結(jié)構(gòu)

2023-11-27 00:55:43

Eureka服務(wù)

2022-09-19 09:41:45

數(shù)據(jù)庫(kù)思維

2024-08-01 20:08:17

2022-02-09 07:03:01

SpringNacos服務(wù)注冊(cè)

2021-04-20 17:20:59

SpringColud EurekaNetflix開(kāi)發(fā)

2021-04-21 12:29:45

KafkaZookeeper模型

2022-06-17 12:05:25

微服務(wù)注冊(cè)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)