第2節( 跟我學Spring Cloud(Finchley版)-02-構建分佈式應用 )說過:
地址硬編碼問題——電影微服務中將用戶微服務的地址寫死,如果用戶微服務地址發生變化,難道要重新上線電影微服務嗎?
本節來解決該問題。
不妨先思考一下,怎樣才能讓服務消費者總能找到服務提供者呢?或者說,怎樣才能讓服務消費者感知到服務提供者地址的變化呢?
TIPS
目前市面上把服務消費者找到服務提供者的這種機制稱爲服務發現,又或者服務註冊。下面來探索服務發現究竟是怎麼回事。
服務發現原理初探
其實,服務發現機制非常簡單,不妨用大家熟悉的MySQL來類比——只需一張表(圖中的registry表)即可實現服務發現!
如圖,如果我們能在:
- 應用啓動時,自動往registry表中插入一條數據,數據包括服務名稱、IP、端口等信息。
- 應用停止時,自動把自己在registry表中的數據的status設爲
DOWN
。
這樣,服務消費者不就永遠都能找到服務提供者了嘛!當服務消費者想調用服務提供者接口時,只需向數據庫發送SQL語句 SELECT * FROM registry where service_name = 'user' and status = 'UP'
即可找到服務提供者的所有實例!IP、端口啥的都有了,自己拼接一下,再去調用就行了!
TIPS
看,服務發現機制是不是很簡單?程序猿給圖中的”MySQL“的組件起了一個牛叉的名字叫:”註冊中心“,也有的書將其稱爲”服務發現組件“。
但,這畢竟只是一個最簡陋的服務發現原理。完整的服務發現要考慮的問題有很多,例如:
- 當服務抑或所在主機突然崩潰或者進入某種不正常的情況無法提供服務(例如應用的數據庫掛了)時,對應的數據理應標記DOWN,或者索性刪除;
- 如果每次調用之前,都得向服務發現組件發送類似
SELECT * FROM registry where service_name = 'user' and status = 'UP'
的語句,那麼服務發現組件的壓力得有多大?更重要的,這與當下流行的去中心化設計的思想相悖; - 服務發現組件即使掛掉,也不應該影響微服務之間的調用。
那麼,一個完善的服務發現組件應該具備哪些能力呢?
服務發現原理深入
不妨來看一下使用服務發現組件後的架構圖,如圖所示。
服務提供者、服務消費者、服務發現組件這三者之間的關係大致如下:
- 各個微服務在啓動時,將自己的網絡地址等信息註冊到服務發現組件中,服務發現組件會存儲這些信息;
- 服務消費者可從服務發現組件查詢服務提供者的網絡地址,並使用該地址調用服務提供者的接口;
- 各個微服務與服務發現組件使用一定機制(例如心跳)通信。服務發現組件如長時間無法與某微服務實例通信,就會自動註銷(即:刪除)該實例;
- 當微服務網絡地址發生變更(例如實例增減或者IP端口發生變化等)時,會重新註冊到服務發現組件;
- 客戶端緩存:各個微服務將需要調用服務的地址緩存在本地,並使用一定機制更新(例如定時任務更新、事件推送更新等)。這樣既能降低服務發現組件的壓力,同時,即使服務發現組件出問題,也不會影響到服務之間的調用。
綜上,服務發現組件應具備以下功能。
- 服務註冊表:服務註冊表是服務發現組件的核心(其實就是類似於上面的registry表),它用來記錄各個微服務的信息,例如微服務的名稱、IP、端口等。服務註冊表提供查詢API和管理API,查詢API用於查詢可用的微服務實例,管理API用於服務的註冊和註銷;
- 服務註冊與服務發現:服務註冊是指微服務在啓動時,將自己的信息註冊到服務發現組件上的過程。服務發現是指查詢可用微服務列表及其網絡地址的機制;
- 服務檢查:服務發現組件使用一定機制定時檢測已註冊的服務,如發現某實例長時間無法訪問,就會從服務註冊表中移除該實例。
綜上,使用服務發現的好處是顯而易見的。Spring Cloud爲我們提供多種服務發現組件的支持,例如Eureka、Consul(spring-cloud-consul)、Zookeeper(spring-cloud-zookeeper)、Aliaba Nacos(孵化中:spring-cloud-alibaba)、Etcd(孵化中:spring-cloud-etcd)等。下一節,本教程將以Eureka爲例,爲大家詳細講解Spring Cloud中的服務註冊與服務發現;基於Consul以及Nacos的服務發現,則會以番外形式出現。
拓展閱讀
- spring-cloud-consul:https://github.com/spring-cloud/spring-cloud-consul
- spring-cloud-zookeeper:https://github.com/spring-cloud/spring-cloud-zookeeper
- spring-cloud-alibaba:https://github.com/spring-cloud-incubator/spring-cloud-alibaba
- spring-cloud-etcd:https://github.com/spring-cloud-incubator/spring-cloud-etcd
本文首發
http://www.itmuch.com/spring-cloud/finchley-4/