偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

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

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

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

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

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

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

分布式帶來的問題

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

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

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

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

看似問題解決了,其實隱患很大:

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

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

用 Redis 解決

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

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

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

簡單流程如下圖所示:

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

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

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

輪詢時間太短依然有性能瓶頸問題,這樣本地緩存也沒有存在的必要了;輪詢時間太長,本地緩存來不及更新,就會存在 "臟" 數(shù)據(jù)。

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

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

定時任務(wù)存在周期性,沒法做到實時,這樣就可能存在請求異常。

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

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

用 Zookeeper 解決

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

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

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

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

Zookeeper的重點特性

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

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

(2)持久節(jié)點(Persistent)

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

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

持久有序節(jié)點是在上面持久節(jié)點的特性上加上了有序性,有序性的意思是服務(wù)向Zookeeper注冊信息時,Zookeeper 根據(jù)注冊順序給每個節(jié)點編號。

(4)臨時節(jié)點(Ephemeral)

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

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

(5)臨時有序節(jié)點(Ephemeral_sequential)

臨時有序節(jié)點是在臨時節(jié)點的基礎(chǔ)上再加上有序性,跟持久有序節(jié)點類似。

(6)節(jié)點監(jiān)聽(Wacher)

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

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

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

了解了Zookeeper的一些重要特性,我們再來看下 Zookeeper 是如何實現(xiàn)服務(wù)注冊和發(fā)現(xiàn)的。還是以訂單服務(wù)、用戶服務(wù)的場景為例。

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

服務(wù)消費方(訂單服務(wù))需要調(diào)用用戶服務(wù)的接口,但因為不知道實例的 ip、端口等信息,只能從 Zookeeper 中獲取調(diào)用地址列表,然后進(jìn)行調(diào)用,這個過程成為服務(wù)的訂閱。

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

服務(wù)注冊原理

服務(wù)啟動后會自動向 Zookeeper 注冊,注冊的規(guī)則如下:

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

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

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

小結(jié)

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

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

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

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

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

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

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

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

文章的最后,我們再次以訂單服務(wù)和用戶服務(wù)為例通過兩張圖生動的詮釋了服務(wù)注冊和動態(tài)發(fā)現(xiàn)的流程和原理。


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

2022-03-07 17:43:30

注冊微服務(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ù)

2023-04-26 01:17:16

惡意注冊Java驗證

2022-04-26 05:36:42

服務(wù)治理模式

2022-02-16 18:00:19

動態(tài)代理代碼靜態(tài)代理

2022-08-16 18:52:20

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

2024-12-27 00:37:46

2014-07-22 10:56:45

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

2021-03-23 10:25:05

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

2022-08-01 10:43:11

RocketMQZookeeper注冊中心

2022-02-07 07:10:32

服務(wù)注冊功能

2023-11-27 00:55:43

Eureka服務(wù)

2022-09-19 09:41:45

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

2024-08-01 20:08:17

2022-02-09 07:03:01

SpringNacos服務(wù)注冊

2021-04-20 17:20:59

SpringColud EurekaNetflix開發(fā)

2022-06-17 12:05:25

微服務(wù)注冊

2021-04-21 12:29:45

KafkaZookeeper模型
點贊
收藏

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