02.27 微服務的輕鬆構建—服務註冊與發現

前言

為什麼需要服務註冊中心?

隨著服務數量的擴張,我們需要服務調用方能夠自動感知到服務提供方的地址,當我們對服務提供方進行橫向擴展的時候,服務調用方能夠自動感知到,這就需要服務提供方能夠在啟動或者關閉的時候自動向註冊中心註冊,而服務調用方直接詢問註冊中心就可以知道具體的服務提供方的地址列表,服務調用方可以自己根據特定的路由算法做負載均衡, 或者服務調用方根本不需要知道服務提供方的具體地址,統一發給一個代理系統,由這個代理系統轉發給對應的服務調用方。所以為了支持服務的彈性擴展,我們需要一個獨立系統做服務發現和負載均衡,目前做服務發現有三種代理模式

集中代理模式

集中代理模式一般是在服務調用方和服務提供方之間部署一套獨立的代理系統來接收調用方的請求,然後配合域名系統和特定的負載均衡策略以及路由算法,轉發到對應的服務提供方,這個代理系統一般由硬件F5設備加7層軟件負載nginx配合域名系統來使用,這種模式,有集中治理,運維簡單,而且和語言棧無關的優點,但是目前這個代理系統存在單點問題,而且配置比較麻煩,由於服務調用者沒有之間調用服務提供方,所以網絡上存在多一跳的開銷,目前國內主要有攜程等公司在使用

微服務的輕鬆構建—服務註冊與發現


客戶端嵌入式代理

目前很多公司用springcloud或者dubbo作為rpc框架的公司多選擇這種模式,在客戶端嵌入一個程序做服務發現和軟件負載均衡,調用方會緩存服務提供方的地址列表,並且自己根據路由算法和負載均衡策略選擇服務提供者進行調用,這種模式需要一個第三方的註冊中心配合,服務提供者啟動的時候將服務註冊到註冊中心,服務調用方去註冊中心獲取服務提供者信息,這種模式有無單點問題,性能好的優點,但是由於客戶端需要關心負載均衡和維護提供者列表,導致客戶端臃腫,目前國內主要有阿里的dubbo和新浪的Motan

微服務的輕鬆構建—服務註冊與發現


主機獨立進程代理

這種模式是前面兩種模式的一個折中,將這個代理放到主機的一個獨立程序上,所有這個主機上的應用共享這個代理,應用一般部署在docker容器中,主機可以是一個物理機也可以是虛擬機。在這個代理上進行路由和負載均衡,這個模式也需要一個模式二中獨立的註冊中心來輔助代理程序做服務發現,這種模式兼具上面兩種模式的優點,但是運維較複雜,目前國內只有唯品會有這種模式的探索

微服務的輕鬆構建—服務註冊與發現


servicemesh介紹

邊車模式,sidecar,將一個單獨的進程用來處理,日誌,健康,限流,服務發現等功能,和應用層完全分離,目前如果我們大多lib等軟件包的形式和應用集成來實現限流和監控,這樣增加了應用依賴,每次lIB包升級都需要將應用重新編譯發佈,而邊車模式下我們可以將邏輯層和控制層分開部署.

邊車模式進化後,將這個獨立程序集群化,就成了servicemesh,也就是CNCF所推薦的新一代微服務架構,將這個代理程序下沉為一個基礎服務,作為平臺開放給應用程序

微服務的輕鬆構建—服務註冊與發現


servicemesh的定義:一作為個輕量級的網絡代理專職處理服務和服務間的通訊,對應用程序透明,用來分離或者解耦和分佈式系統架構中控制層的上的東西.

類似於網絡七層模型中的TCP協議,將底層那些難控制的網絡通訊方面的東西(擁塞控制,丟包重傳,流量控制)都處理了,而上層的http協議就只用關心應用層的html格式

演化路徑

  • 1.一開始最原始的兩臺主機之間進程直接通訊
  • 2.然後分離出網絡層來,服務間的遠程通信通過底層的網絡模型
  • 3.由於兩邊服務由於接收速度不一致,需要在應用層做流控
  • 4.然後流控模塊交給網絡層去處理,最後TCP演化成為世界上最成功的網絡協議
  • 5.類比分佈式架構中,我們在應用層加入了限流,熔斷,監控,服務發現等功能
  • 6.然後我們發現這些控制層的功能都可以標準化,我們將這些功能分別做成LIB嵌入到應用中,這樣誰需要這個功能只要加入這個LIB就好了
  • 7.最後我們發現這些LIB不能跨編程語言,然後有什麼改動就需要重新編譯發佈服務,不太方便,應該有一個專門的層來幹這個,就是sidecar
  • 8.然後sidecar集群就成了Service mesh ,成為了一個基礎設施
微服務的輕鬆構建—服務註冊與發現


目前開源的servicemesh實現有istio

為什麼zookeeper不適合做服務發現

  • 首先我們分析下服務發現是滿足cap裡面的ap還是cp

註冊中心提供了兩個服務,一個是讓服務提供方註冊,就是寫數據,另一個是讓服務調用方查詢,就是讀數據,當註冊中心集群部署後,每個節點都可以對外提供讀寫服務,每一次寫請求都會同步到其他節點,這樣才能讓其他節點提供的讀服務正確,如果節點之間的數據複製出現不一致,那麼將導致服務調用方獲取到的服務提供者列表中要麼出現已經下線的節點,要麼少提供了一個正常的節點,提供了下線的節點,服務調用者可以通過重試機制調用其他節點,出現少提供一個正常節點則導致服務提供方的流量不均勻,這些都是可以接受的,何況各個節點最終都會同步成功,也就是數據最終一致性,所以我們希望註冊中心是高可用的,最好能滿足最終一致性,而zookeeper是典型的CP設計,在網絡分區情況下不可用,當節點超過半數掛掉不可用,違背了註冊中心不能因為自身任何原因破壞服務本身的可連通性

  • 另外我們分析下出現網絡分區的情況

我們看下下圖zookeeper三機房5節點部署的情況下,如果機房3和機房1機房2網絡出現分區成為孤島,zookeeper和機房3裡的其他應用不能和外部通信,zookeeper由於聯繫不是leader將不可用,雖然zookeeper整個集群中其他4個節點依然可以對外提供服務,但是zookeeper為了保證在腦裂的情況下數據一致性,機房3的節點5將不能進行讀寫服務,這個時候機房3內的應用A雖然不能調用其他機房的服務B但是可以調用機房3內的服務B,但是由於Zookeeper5不能讀寫,所以機房內也不能讀寫,這對應用來說是完全不能接受的,我們有時候為了性能考慮還好主動修改路由策略讓應用盡量同機房調用,試想一下如果三個機房都出現網絡分區相互成為孤島,那麼整個應用將不可用

  • zookeeper的寫服務並不支持水平擴展

zookeeper需要和所有的服務保持長連接,而隨著服務的頻繁發佈,以及服務的健康檢查,會導致zookeeper壓力越來越大,而zookeeper並不能通過橫向擴展節點解決,可以提供的方案是按照業務進行拆分到不同的zookeeper集群

  • 健康檢查

服務提供方是否可用,不能僅僅通過zookeeper的session是否存活判斷,TCP活性並不能反映服務的真實健康狀態,而需要完整的健康體系,CPU,內存,服務是否可用,數據庫是否能聯通等

幾個註冊中心的對比


微服務的輕鬆構建—服務註冊與發現


分享到:


相關文章: