日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

美团面试:如何设计一个注册中心?

發布時間:2025/3/15 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 美团面试:如何设计一个注册中心? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

?今天,給大家分享如何設計一個注冊中心

不管是出于面試,還是深入學習注冊中心,關于如何設計一個注冊中心都是一個很好的話題。

假設現在我們系統有兩個小系統:

  • 訂單系統

  • 商品系統

單個系統分別部署在不同服務器上,如果我們訂單系統需要調用商品系統的某個服務:


怎么調用?

方法1:商品系統開發的朋友告訴你對應的地址。


方法2:商品系統開發的朋友把對應API地址存放到某個地方。


方法3:直接通過Nginx,使用域名進行轉發到某個實例上。


這時候,訂單系統就可以通過上述方法調用商品系統的API了。

問題來了

實際線上環境中,很少是單體機構的,很多都是做了集群的,也就是說每個服務會有N個實例,少則幾個幾十個,多則幾百上千上萬。如果此時我們還用上面三種方法,當我們的商品系統某個服務下線(宕機了),或者新增實例,此時是非常的頭疼。

所以,注冊中心就來了。

注冊中心來了

我們能不能搞一個第三方的節點,這個節點就用來存放我們商品系統的服務信息,這樣一來,其他系統需要服務信息,直接去第三方節點上去獲取即可。此時,其他系統只要知道這個第三方的節點地址就可以了。這個第三方的節點,我們也稱之為注冊中心。

下面我們用服務提供方(商品系統)稱之為provider,服務調用方(訂單系統)我們稱之為consumer。

如何設計一個注冊中心

我們需要解決如下幾個問題:

  • 服務如何注冊

  • consumer如何知道provider

  • 服務注冊中心如何高可用

  • 服務上下線,消費端如何動態感知

服務注冊


當我們把服務信息注冊上去后,就應該是:


服務列表保存通常有三種方式:本地內存、數據庫、第三方緩存系統

注冊上去后,consumer需要服務地址的時候,就可以用相應key去注冊中心獲取對應的服務列表。


同一個服務注冊中心,我們可以注冊多個服務,比如用戶服務、商品服務、訂單服務...

服務消費


consumer端通過key獲取指定的服務地址列表。

以上的還是蠻簡單的吧,簡單來說,我們就是引用了一個第三方的服務來存放我們的服務提供者列表。并且以key-value的形式存儲,key我們可以理解為服務名稱,value就是服務實例列表。


注冊中心高可用

高可用無非就是做集群,我們可以對注冊中心部署多個節點。在消費端consumer只需要知道一個服務注冊中心集群地址cluster-url即可。


動態感知服務上下線

consumer拿到服務列表后,會把服務列表保存起來,保存到本地緩存里。


consumer通過一定的負載均衡算法,選擇出一個地址,最后發起遠程的調用。


如果我們的服務節點掛掉一個了,怎么辦?


此時,服務注冊中心的服務列表還是之前的列表,如果consumer調用到過掉的節點上,那豈不是會出問題呀。

所以,我們的服務注冊中心需要知道哪個服務節點掛了,然后從對應服務列表里刪除。

有種辦法叫做心跳檢測heartBeat,即就是服務注冊中心,每隔一定時間去監測一下provider,如果監測到某個服務掛了,那就把對應服務地址從服務列表中刪除。

根據心跳檢測,來提出無效服務。


可是不對呀,此時consumer端本地列表里還有過掉的服務地址,怎么辦呢?

或者是,在增加一個新的服務節點


對于服務注冊中心來說,就是服務列表里增加一個服務地址。

但是在消費端存在同樣的問題,就是服務注冊中心的服務列表和consumer端的服務列表不一樣了。

如何讓consumer端也動態感知呢?

其實很簡單,此時,我們得思維換一下,因為consumer的服務列表是來自于服務注冊中心,我們就可以把consumer理解為消費端,服務注冊中心理解為服務端。此時,consumer端就可以去服務端(服務注冊中心)拉取provider服務列表。

通常有兩種方案:push和pull

  • push:服務注冊中心主動推送服務列表給consumer。

  • pull:consumer主動從注冊中心拉取服務列表。


不管是push還是pull,都會存在consumer和服務注冊中心的通信管道。如果他們之間斷開了,那就無法獲取服務列表了。

還有就是服務注冊中心知道consumer的地址,比如

我得知道你的微信好友,不然我怎么把我手里的資源發給你

我們的網絡通信,必然會存在監聽的動作。

如果服務注冊中心要push到consumer,此時他們之間需要建立一個會話,所以,在服務注冊中心會維護一個會話管理的模塊。還有一種方式就是consumer提供一個API,這個API給服務注冊中心進行回調。

本質是我們是使用HTTP協議還是使用Socket監聽

push有個不好點,那就是服務注冊中心需要維護大量的會話,而且還需要對每個會話維持一個心跳,一遍知曉這些會話狀態,得確保這些consumer能收到數據,

另外就是pull,pull其實就相對push就簡單多了。pull和我們前面說的心跳機制是類似的,consumer端啟動定時任務,每個多久拉取服務注冊中心的服務列表。pull也不需要去維護大量的會話,我只需要每隔多久調用接口拉取服務列表即可。但是這里還是會存在一個問題,因為是定時去拉取,所以會存在一定的數據延遲,比如consumer剛剛拉取服務列表,但就在拉取結束的后,某個服務provider掛了,consumer就要等下次拉取才知道對應服務provider掛了。

如果定時任務是每隔30秒拉去一次,那就是說,延遲最長時間是30秒。

還有一種方式long-pull,也叫長輪詢,是上面兩種方案的優化方案,consumer發起拉取請求時,先把這個請求hold住,當服務注冊中心有發生變化后,consumer端能立馬感知。

關于長輪詢:

與簡單輪詢相似,只是在服務端在沒有新的返回數據情況下不會立即響應,而會掛起,直到有數據或即將超時

優點:實現也不復雜,同時相對輪詢,節約帶寬

缺點:還是存在占用服務端資源的問題,雖然及時性比輪詢要高,但是會在沒有數據的時候在服務端掛起,所以會一直占用服務端資源,處理能力變少

應用:一些早期的對及時性有一些要求的應用:web IM 聊天

這樣,我們就搞定了所謂的服務上下線動態感知。

通過上面的服務注冊、服務消費、注冊中心高可用以及動態感知服務的上下線,這就是我們去實現一個服務注冊中心的通用模型。

小總結

關于如何設計一個注冊中心,無非重點關以下幾點:

  • 服務是如何注冊

  • 消費端如何獲取服務

  • 如何保證注冊中心的高可用

  • 動態感知服務的上下線

有道無術,術可成;有術無道,止于術

歡迎大家關注Java之道公眾號

好文章,我在看??

?

總結

以上是生活随笔為你收集整理的美团面试:如何设计一个注册中心?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。