天天看點

談一談我所了解的微服務中的注冊中心

雲栖号資訊:【 點選檢視更多行業資訊

在這裡您可以找到不同行業的第一手的上雲資訊,還在等什麼,快來!

微服務現在是一個很火的話題,好像不管項目的大小,适用範圍都在往微服務上去靠。這也使得現在如果不會微服務出去都沒法和别人聊了。

僅從我自己的工作經曆來看,盡管我們的項目也是微服務化了的。但是說實話在業務開發過程中并沒有體會到微服務的開發和單體項目開發中存在很大的差別(僅業務開發這一塊來說)。

微服務的學習單獨的寫幾個demo并沒有啥用,現在的架構封裝程度都很高,就算是代碼跑起來來依舊是雲裡霧裡。微服務的學習更多的是搞清楚微服務中每一個元件到底是什麼?為什麼有這些元件?沒有會怎麼樣?功能大概是怎麼實作的?

搞清楚來這些基本上就可以說對微服務有個大體的掌握了。

為什麼需要注冊中心

在微服務中首先需要面對的問題就是不同的服務之間如何進行通信呢?在單體服務中如果不同的服務之間需要通信,一般就是服務将接口暴露,然後其他的服務通過http進行請求,那麼很明顯在微服務中也可以這樣。

但這裡存在的問題在于單體服務中我們需要請求的目标是我們在請求的url中直接寫死的,因為服務不多可以這樣。而微服務中需要考慮的是存在大量服務時手動維護服務清單是否合适?如果服務橫向擴充時如何通知其他的服務?服務當機後,如何及時下線等等問題。

注冊中心的功能

注冊中心的存在是為了更好更友善的管理應用中的每一個服務,是各個分布式節點之間的紐帶。注冊中心主要提供以下核心功能:

  • 服務注冊與發現:動态的增減服務節點,服務節點增減後動态的通知服務消費者,而不需要由消費者來更新配置。
  • 服務配置:動态修改服務配置,并将其推送到服務提供者和服務消費者而不需要重新開機服務。
  • 健康檢查和服務摘除:主動的檢查服務健康情況,對于當機的服務将其摘除服務清單。

注冊中心的實作

注冊中心的主要功能就是儲存服務的具體資訊,然後由服務消費者讀取這些資訊。從整體的流程上來說大概就是這樣:

談一談我所了解的微服務中的注冊中心

除了将服務注冊到注冊中心,實際還存在服務的反注冊

目前對注冊中心的實作分為兩種模式,分别為用戶端(應用内注冊)和服務端(應用外注冊)。

用戶端注冊中心

目前用戶端實作的注冊中心比較有代表性的就是eureka,雖然eureka2.0版本在此前宣布閉源,但目前好像沒有太大的影響。後續的話可以考慮阿裡開源的nacos。

eureka是一個基于Java語言實作的費用與服務發現與注冊的元件,包含服務端和用戶端兩部分。

服務端主要用來存儲服務資訊,定時進行服務檢查。而用戶端用于完成向服務端注冊服務資訊以及從服務端拉取服務資訊等。

談一談我所了解的微服務中的注冊中心

上圖是eureka官給出的eureka的架構圖。

從圖中可以很明顯的看到eureka的服務端也是作為一個服務部署,而用戶端則是通過sdk的方式接入應用。用戶端向服務端進行服務注冊以及更新服務等,同時用戶端從服務端擷取服務資訊,不同服務之間根據獲得的服務資訊進行遠端調用。

為了滿足服務的高可用,通過移動多個eureka server服務,不同eureka server互相注冊實作服務的高可用。

服務端注冊中心

eureka是由注冊中心提供服務端和用戶端的SDK,業務端通過引入注冊中心提供的SDK,來實作服務的注冊和發現。而服務端的注冊中心則是通過應用外的元件來實作服務注冊功能的。目前用的比較多的服務端注冊中心元件如zookeeper、consul等。這裡以zookeeper為例。

Zookeeper 是 Apache Hadoop 的子項目,是一個樹型的目錄服務,支援變更推送,适合作為 Dubbo 服務的注冊中心,工業強度較高,可用于生産環境,是目前Dubbo官方主推搭配的注冊中心。

談一談我所了解的微服務中的注冊中心

上圖是dubbo官網提供的zookeeper作為注冊中心的基本原理。

以dubbo為根目錄,建立一服務接口全限定名的目錄,在其下建立存放服務提供者接口資訊的providers目錄、存放服務消費者接口資訊的consumers目錄、存放服務配置資訊的configurators目錄等。

服務提供者啟動的時候在providers下建立一條服務資訊,該資訊可以被consumer擷取。通過zk提供的watcher機制注冊一個watcher在服務提供者的providers目錄下,這樣當服務出現擴容或者當機的時候就可以立即被consumer消費。

注冊中心的問題

在微服務中,注冊中心作為一個存儲所有服務中心的地方必然不可能是單機的。因為如果注冊中心無法使用,那麼服務提供者就無法對外暴露自己的服務,消費者也無法擷取自己需要調用的服務的具體位址,整個應用将會崩潰。首先需要保證的就是注冊中心的高可用。

一緻性和可用性的抉擇

說到高可用,CAP理論是繞不過去的,CAP簡單來說就是我們需要在服務的可用性和服務間的一緻性進行一個抉擇。是犧牲可用性來保證強一緻性還是保證可用性犧牲強一緻性呢?

CP類型注冊中心

Zookeeper是一個典型的CP類型的高可用元件。zookeeper實作來paxos算法,zookeeper叢集有一個節點作為leader,如果leader節點挂了zk會通過ZAB協定來進行leader選舉,但是在選舉的過程中zk是不能對外提供服務的。

而且當因為網絡分區導緻zk叢集出現腦裂問題時,由于ZAB協定需要半數以上的節點參與,是以可能會有部分或者全部的zk節點無法對外提供服務。但是zk可以保證所有可用節點都資料都是一緻,即使節點崩潰,在恢複後也會和其他節點保持一緻,這就是zk犧牲了可用性而保證的強一緻性。

AP類型注冊中心

而類似與eureka的注冊中心則是AP類型的。eureka實作高可用是通過啟動多個eureka server服務,每一個eureka server即是提供者也是消費者,每個eureka server将自己作為服務注冊給其他的eureka server,這樣每個eureka server都是其他server 的replica。eureka這種模式中每個節點都是平等的,不存在leader、flower。

當叢集中某一個server節點當機,請求可以直接轉移到其他節點。即使發生了網絡分區,盡管不同分區之間無法進行通信,但是在每一個分區内的節點是通信并且可以正常對外提供服務,這樣就保證了在server節點當機的情況下的注冊中心的可用性。

而問題在于由于不同分區無法通信,就導緻可能一部分節點的資料和另一部分有差别,這就是犧牲了強一緻性來換取系統可用性。

注冊中心的選擇

首先我們應該明确的是其實注冊中心的存在與否應該是不能直接影響服務的調用的。服務之間的調用時通過http或者rpc等協定直接調用的,注冊中心隻是提供一個調用位址。服務是否可以正常使用不能直接靠注冊中心節點資訊來決定。

即使注冊中心出現問題,隻要服務本身沒有當機,理論上來說還是應該正常對外提供服務。是以很明顯對于我們來說AP類型的注冊中心是要優于CP類型的注冊中心的。

當然在實際實作過程中很多架構都會盡可能的去修補這些問題,比如eureka會定時的同步各個節點的資料,盡可能的做到資料一緻性。dubbo的zk注冊中心實作過程中也會本地緩存服務資訊并不是完全通過zk資訊來決定是否剔除服務等。是以實際在選擇時還是需要根據自身實際以及是否還有其他需求來确定。

混合語言開發

在微服務中,每一個服務都是一個獨立的整體。各個服務之間并不向單體應用中的不同子產品大都要求是同一語言實作。現如今各大公司開發語言是多樣化的,不同的業務線開發的語言可能都不盡相同,混合語言是我們必須要面對的一個問題,是以出現了多語言之間服務調用的問題。

對于像eureka這樣的應用内的注冊中心。由于服務的注冊與發現都是依賴于SDK,是以如果要使用eureak那需要對應的語言實作的SDK,目前有不少語言都有提供如python、node.js。目前springclould的Sidecar元件也可以做到将其他語言納入到springclould體系中來。

對于應用外的注冊中心,一般會由這些中間件提供用戶端操作實作。然後由語言本身來實作服務注冊和治理等功能。目前很多語言實際上也有相關的開源工程。

節點存活判斷

前面已經說過了保證CP類型的強一緻性注冊中心以及AP類型保證可用性的注冊中心。而對于一個注冊中心來說最重要的就是管理其中的節點資訊。服務啟動的時候需要将服務資訊記錄,當服務出現問題的時候需要将服務摘除。

但是問題在于如何實作這個摘除的操作,目前注冊中心的實作都是通過心跳檢測來判斷服務的健康狀态。正常情況下如果服務當機了,心跳檢測無法和服務通信判斷該節點無法正常服務,将服務從注冊中心摘除,這個過程是沒有問題的。但是如果發生網絡問題,比如網絡抖動或者網絡分區,這時候心跳檢測肯定是無法正常通信的,但如果就是以直接将服務摘除那肯定是有問題的,因為節點實際上是能夠正常提供服務的。

是以需要有機制來確定這個過程不會粗暴的将節點從注冊中心摘除。

用戶端判斷

目前很多的架構實作都會在本地緩存微服務的節點資訊。實際上使用這些節點的是各個服務,服務是否能正常使用,這些節點才是最有發言權的。

用戶端緩存了節點資訊,當服務端判定服務出現問題後發出更新請求時,用戶端并不立刻删除,可以先做一個辨別。後續的業務請求過來後,仍舊判定該服務時可用的,隻有當發出的請求無法收到正常回應時才将該服務摘除。由用戶端來決定節點是否可用,不過這需要容錯機制來支援。

動态設定心跳檢測

在網絡頻繁抖動的情況下,注冊中心的節點資訊會快速變化,也會給用戶端發送大量的資訊,當服務較多的時候可能會有大量的帶寬被占用導緻正常的請求都無法處理。

是以需要一種動态的調整注冊中心心跳檢測頻率的機制,當檢測到網絡抖動頻繁時,根據網絡情況調整心跳檢測的頻率,比如調整為正常情況下的1/2,10/1等。在網絡正常時心跳檢測也恢複正常。

小結

注冊中心是微服務架構中一個很關鍵的元件,其保證來各個服務之間正常調用,以及服務的橫向擴容等功能。在進行注冊中心選型時需要考慮業務場景。

【雲栖号線上課堂】每天都有産品技術專家分享!

課程位址:

https://yqh.aliyun.com/live

立即加入社群,與專家面對面,及時了解課程最新動态!

【雲栖号線上課堂 社群】

https://c.tb.cn/F3.Z8gvnK

原文釋出時間:2020-05-15

本文作者:不能摸魚啦

本文來自:“

掘金

”,了解相關資訊可以關注“掘金”

繼續閱讀