談一談我所理解的微服務中的註冊中心

微服務如今是一個很火的話題,好像無論項目的大小,適用範圍都在往微服務上去靠。這也使得如今若是不會微服務出去都無法和別人聊了。node

僅從我本身的工做經從來看,儘管咱們的項目也是微服務化了的。可是說實話在業務開發過程當中並無體會到微服務的開發和單體項目開發中存在很大的區別(僅業務開發這一塊來講)。python

微服務的學習單獨的寫幾個demo並無啥用,如今的框架封裝程度都很高,就算是代碼跑起來來依舊是雲裏霧裏。微服務的學習更多的是搞清楚微服務中每個組件究竟是什麼?爲何有這些組件?沒有會怎麼樣?功能大概是怎麼實現的?git

搞清楚來這些基本上就能夠說對微服務有個大致的掌握了。算法

爲何須要註冊中心

在微服務中首先須要面對的問題就是不一樣的服務之間如何進行通訊呢?在單體服務中若是不一樣的服務之間須要通訊,通常就是服務將接口暴露,而後其餘的服務經過http進行請求,那麼很明顯在微服務中也能夠這樣。spring

但這裏存在的問題在於單體服務中咱們須要請求的目標是咱們在請求的url中直接寫死的,由於服務很少能夠這樣。而微服務中須要考慮的是存在大量服務時手動維護服務列表是否合適?若是服務橫向擴展時如何通知其餘的服務?服務宕機後,如何及時下線等等問題。緩存

註冊中心的功能

註冊中心的存在是爲了更好更方便的管理應用中的每個服務,是各個分佈式節點之間的紐帶。註冊中心主要提供如下核心功能:markdown

  • 服務註冊與發現:動態的增減服務節點,服務節點增減後動態的通知服務消費者,而不須要由消費者來更新配置。
  • 服務配置:動態修改服務配置,並將其推送到服務提供者和服務消費者而不須要重啓服務。
  • 健康檢查和服務摘除:主動的檢查服務健康狀況,對於宕機的服務將其摘除服務列表。

註冊中心的實現

註冊中心的主要功能就是保存服務的具體信息,而後由服務消費者讀取這些信息。從總體的流程上來講大概就是這樣: 網絡

註冊中心流程

除了將服務註冊到註冊中心,實際還存在服務的反註冊架構

目前對註冊中心的實現分爲兩種模式,分別爲客戶端(應用內註冊)和服務端(應用外註冊)。框架

客戶端註冊中心

目前客戶端實現的註冊中心比較有表明性的就是eureka,雖然eureka2.0版本在此前宣佈閉源,但目前好像沒有太大的影響。後續的話能夠考慮阿里開源的nacos。

eureka是一個基於Java語言實現的費用與服務發現與註冊的組件,包含服務端和客戶端兩部分。

服務端主要用來存儲服務信息,定時進行服務檢查。而客戶端用於完成向服務端註冊服務信息以及從服務端拉取服務信息等。

git-eureka

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

從圖中能夠很明顯的看到eureka的服務端也是做爲一個服務部署,而客戶端則是經過sdk的方式接入應用。客戶端向服務端進行服務註冊以及更新服務等,同時客戶端從服務端獲取服務信息,不一樣服務之間根據得到的服務信息進行遠程調用。

爲了知足服務的高可用,經過移動多個eureka server服務,不一樣eureka server相互註冊實現服務的高可用。

服務端註冊中心

eureka是由註冊中心提供服務端和客戶端的SDK,業務端經過引入註冊中心提供的SDK,來實現服務的註冊和發現。而服務端的註冊中心則是經過應用外的組件來實現服務註冊功能的。目前用的比較多的服務端註冊中心組件如zookeeper、consul等。這裏以zookeeper爲例。

Zookeeper 是 Apache Hadoop 的子項目,是一個樹型的目錄服務,支持變動推送,適合做爲 Dubbo 服務的註冊中心,工業強度較高,可用於生產環境,是目前Dubbo官方主推搭配的註冊中心。

zk

上圖是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等。在網絡正常時心跳檢測也恢復正常。

小結

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

相關文章
相關標籤/搜索