1)微服務為什么要使用服務發現與注冊?
前文中提到,微服務獨立部署、具有清晰的邊界,服務之間通過遠程調用來構建復雜的業務功能。那為什么要引用服務注冊與發現呢?服務注冊與發現具體要解決什么問題?
服務注冊與發現主要解決了如下兩個重要問題:
1)屏蔽,解耦服務之間相互依賴的細節
我們知道服務之間的遠程調用必須要知道對方的IP、端口信息。我們可以在調用方直接配置被調用方的IP、端口,這種調用方直接依賴IP、端口的方式存在明顯的問題,如被調用的IP、端口變化后,調用方法也要同步修改。
通過服務發現,將服務之間IP與端口的依賴轉化為服務名的依賴,服務名可以根據具微服務業務來做標識,因此,屏蔽、解耦服務之間的依賴細節是服務發現與注冊解決的第一個問題。
2)對微服務進行動態管理
在微服務架構中,服務眾多,服務之間的相互依賴也錯綜復雜,無論是服務主動停止,意外掛掉,還是因為流量增加對服務實現進行擴容,這些服務數據或狀態上的動態變化,都需要盡快的通知到被調用方,被調用方才采取相應的措施。因此,對於服務注冊與發現要實時管理者服務的數據與狀態,包括服務的注冊上線、服務主動下線,異常服務的剔除。
服務發現將服務IP、端口等細節通過一個服務名抽象給調用者,並動態管理者各個微服務的狀態檢測、狀態更新,服務上線,下線等,這些都是微服務治理的基礎,包括,負載均衡,鏈路跟蹤。
對於服務發現與注冊 一般有兩種實現模式:服務器端模式,客戶端模式。
2)微服務發現的服務器端模式
服務器端模式通過使用一個中間的服務器,來屏蔽被調用服務的復雜性與變動性,當有新的服務加入或老服務剔除時,只需要修改中間服務器上的配置即可,此模式的顯著特點是:引入獨立的中間代理服務器來屏蔽真實服務的具體細節。
如下圖所示:服務A是調用方(消費者),服務B是被調用方,微服B有三個負載,分別部署在三台IP為100、101、102的機器上。當服務A要調用服務B時,先通過DNS域名解析找到Nginx服務器,然后將請求發送給Nginx,因為在Nginx上配置了服務B的真實訪問地址,Nginx收到請求后根據負載均衡算法,將請求轉發到某個真實的服務B,服務B將請求結果返回給Nginx,Nginx再將返回結果給服務A,整個請求流程結束。
當然中間服務器不一定非得Nginx,還可以時基於硬件的F5,也可以工作在傳輸層的IP負載均衡等。
該模式的優點是:配置集中在獨立的中間服務器端完成,對代碼沒有任何入侵,也不存在跨平台跨語言的問題。因為,所有請求都需要穿透中間服務器,缺點也很明顯:中間服務器會成為一個單點,對性能也會有所影響。

3)微服務發現客戶端模式(進程內)
我們再看客戶端模式(下圖),應用場景還是一樣,服務A要調用服務B,服務B有三個負載。服務A調用服務B時,不需要通過中間服務器,而是在自己進程內維護了服務B的信息,再通過負載算法選擇一個服務B直接調用。那服務A具體是怎么維護服務B的信息呢?為此引入了服務注冊中心的概念,當服務B啟動時向注冊中心注冊自己(將自己的信息發送到注冊中心的注冊表里),服務A再從注冊中心獲取所有注冊的服務,這就是客戶端模式的基本原理。

客戶端模式因為在進程內直接調用服務,也叫做進程內負載,由於不需要穿透中間服務器,所以客戶端模式的性能損耗比較小。但是,需要在服務內部維護服務注冊信息,負載算法等,有一定的代碼入侵性,對於跨平台,跨語言的支持不太友好。
服務發現的兩種模式各有優缺點,也適用於不同的場景,對於大型應用一般會有多層負載,外層用服務器端負載均衡,內部用客戶端負載均衡。下面將重點介紹Netflix的Eureka服務發現組件,我們會從設計理念與原理,代碼實現等多個維度進行解析。
微服系列文章
第1篇: “四個維度” 講明白什么是微服務!
第2篇: 微服務涉及的技術生態有哪些?
第3篇: 微服務-為什么要有服務發現與注冊?
轉自:
版權聲明: 本文為 InfoQ 作者【攀岩飛魚】的原創文章。
原文鏈接:【https://xie.infoq.cn/article/13a6973621381b27bbcd9ab45】。文章轉載請聯系作者。