服務治理在微服務架構中扮演著至關重要的角色,它使得各個微服務能夠自動完成註冊和發現。本文將深入探討實現服務治理的基本方法。
首先,設想我們正在構建一個分散式服務系統。在這種系統中,服務的數量可能非常龐大,並且服務之間需要相互溝通,形成錯綜複雜的呼叫路徑。
面對眾多服務,我們通常會遇到兩個主要問題:
如何有效追蹤服務例項的數量?
如何監控服務例項的當前狀態?
當系統中服務數量激增,例如達到數十甚至數百個時,我們很難清楚地瞭解哪些服務正在執行。而且,由於自動擴充套件、服務重啟等操作,服務例項的執行狀態也會頻繁變動。如下圖所示:
爲了更清晰地描述服務的執行狀態,我們可以對每個服務例項進行抽象化處理,並採用統一且直觀的方式來表達這些資訊。如下所示:
但是,隨著服務數量的增加和服務例項狀態的不斷變化,我們如何有效管理這些例項呢?這正是服務治理所要解決的問題。通常,爲了實現高效的服務治理,我們會引入註冊中心來管理服務例項。
什麼是註冊中心
註冊中心是一個儲存服務例項資訊的倉庫,同時也是服務提供者和消費者進行交流的樞紐。它主要提供兩項核心功能:服務註冊和服務發現。
我們看這張服務註冊流程圖就知道,對於註冊中心而言,服務的提供者和消費者都相當於是它的客戶端,所以都內嵌了專門與註冊中心實現互動的客戶端元件。
服務提供者在啟動時,會透過註冊中心的客戶端元件自動註冊自己,這個過程也被稱作服務釋出。對於服務消費者而言,他們執行的是訂閱操作,而非註冊操作。透過訂閱,消費者能夠自動從註冊中心獲取已註冊服務提供者的資訊,這個過程就是服務發現。
我們還可以看到,服務消費者和提供者之間存在一個明顯的區別:消費者擁有一個本地快取,儲存了他們獲取到的服務提供者例項資訊。
這個本地快取有兩個主要作用:一是提高服務發現效率,消費者可以透過查詢本地快取快速獲取目標服務例項資訊;二是在註冊中心不可用或網路異常時,消費者依然可以基於本地快取呼叫已註冊的服務。
註冊資訊變更通知機制
講到這裏,我們實際上就已經瞭解了 。透過獲取註冊中心中的服務例項資訊,我們就可以掌握系統中服務的數量以及當前的執行時狀態了。
但問題來了,一旦服務的執行狀態發生變化,我們如何及時獲取這些變更資訊呢?這就需要在註冊中心引入變更通知機制:
變更通知機制是實現註冊中心的一大難點,因為這個過程涉及服務提供者、消費者和註冊中心三者之間的資料同步問題,想要在分佈式環境下實現資料同步是有挑戰的。接下來,我將介紹兩種主流的實現方法:監聽機制和輪詢機制。
監聽機制
從架構設計角度來看,狀態變更管理可以利用註冊中心的釋出-訂閱模式。因此也就誕生了服務監聽機制。它確保服務消費者能夠實時監控服務的更新狀態,是一種被動接收變更通知的方案,通常採用監聽器和回撥機制。
服務消費者可以為具體的服務例項節點新增監聽器。當這些節點發生變化時,例如服務 B 的第一個例項不可用、服務 C 的第一個例項地址變更,或服務 D 新增了一個例項 3,註冊中心就會觸發監聽器中的回撥函式,確保更新通知到每一個服務消費者。
輪詢機制
另一種確保狀態資訊同步的方式是輪詢機制,這是一種主動拉取策略。服務消費者會定期呼叫註冊中心的服務獲取介面,以獲取最新的服務列表,並更新本地快取。
輪詢機制實際上是一個定時器,我們需要考慮的主要問題是輪詢頻率。爲了確保資料同步的及時性,輪詢頻率不能太短;但同時,考慮到輪詢對註冊中心效能的影響,也不能過於頻繁。通常,將輪詢頻率控制在幾十秒到幾分鐘之間是一個較好的選擇。
註冊中心實現
透過前面的分析,相信你對註冊中心的實現原理有了全面的瞭解。註冊中心本質上是一種架構模型。在開發過程中,爲了避免重複勞動,我們通常不需要自己實現這一模型,而是可以採用業界的一些主流注冊中心實現工具,如 Consul、Zookeeper、Eureka 和 Nacos。
Consul 由 HashiCorp 公司提供,主要用於分佈式環境下的服務發現與配置;Zookeeper 是 Apache 的一個頂級專案,作為分散式協調領域的代表性框架,被廣泛用於註冊中心、配置中心和分散式鎖等場景;Netflix 的 Eureka 採用了一種不同的實現方案,並整合到了微服務開發框架 Spring Cloud 中;Nacos 由阿里巴巴開發,是面向雲原生應用的動態服務發現、配置和服務管理平臺。
這些工具各有特點,都實現了註冊中心的高可用性、服務例項儲存和同步功能,並提供了方便整合的客戶端元件。我們知道,註冊中心主要應用於微服務系統,主流的微服務開發框架是 Dubbo 和 Spring Cloud,它們分別使用 Zookeeper 和 Eureka 作為預設的註冊中心實現方案。
因此,接下來我們就重點探討下這兩款註冊中心工具。
Zookeeper 是“服務監聽機制”實現策略的典型代表,它本質上是一個樹形結構,可以在樹上建立臨時節點,並對節點新增監聽器。
臨時節點的客戶端與該節點建立長連線,並實時關注節點狀態。客戶端有一個回撥函式,當節點狀態變化時,透過監聽器將變化傳遞到客戶端並觸發回撥函式。如下圖所示:
而對於 Netflix Eureka 而言,它採用的就是典型的“輪詢機制”來實現服務例項狀態的同步,如下所示:
在 Eureka 中,客戶端和伺服器端透過傳送心跳來實現輪詢機制。Eureka 有一個租約概念,服務提供者需要透過續約機制來確保註冊中心中的服務例項狀態得到更新。心跳的作用是完成續約操作。
一般來說,心跳頻率是 30 秒,如果服務連續 90 秒沒有傳送心跳,Eureka 伺服器會認為該服務失效,並更新其狀態資訊。這樣,可以確保 Eureka 伺服器中服務例項資訊的正確性。
服務消費者也是透過輪詢機制來獲取服務提供者的例項資訊,其預設輪詢頻率同樣是 30 秒。
總結
你只需要記住,註冊中心是一種服務治理工具,它可以管理所有服務例項的執行狀態,並將這些狀態的變化同步到各個服務中。在開發分散式系統時,透過引入註冊中心,可以輕鬆實現對大規模服務的高效治理。