微服務設計模式—服務註冊與發現
在Monolithic模式中,各個元件間通常通過函式形式呼叫。但在微服務架構中,每個微服務通常有多個例項,每個例項具有不同的位置,而且例項會動態變化,比如在負載發生變化時服務會進行擴容或縮容,或者某個例項所在的VM/Container故障後發生遷移,都會導致服務例項地址的變化。因此使用微服務架構開發的應用,必須通過服務註冊和發現技術解決此問題。
微服務例項在scaling或故障時例項數發生變化
服務註冊
服務要被使用,就需要對外提供服務的位置資訊,這個位置資訊通常是一個IP地址+埠。在服務只有單個例項並且地址不會動態變化的情況下,服務的位置在使用端可以通過配置檔案甚至程式碼等方式固定死。但在位置資訊會動態發生變化的情況下,服務例項就需要將這個地址註冊到一個註冊中心。
服務註冊
服務的所有例項在自己可以對外提供服務後,將位置註冊到一個ServiceRegistry服務。這個服務具有固定的位置或域名,負責儲存所有服務例項的位置資訊。
在使用ServiceRegistry時,服務例項要在無法提供服務時取消註冊。ServiceRegistry需要通過心跳等方式核查出無法提供服務的例項,並將例項自動取消註冊。
服務註冊有Self Registration和3rd Party Registration兩種方式。Self Registration需要由每個服務例項自己實現服務的註冊和取消註冊的程式碼,3rd Party Registration則由第三方的Registrar完成服務的註冊和取消註冊。
ServiceRegistry通常會使用如etcd、zookeeper、consul等具備分散式一致性的key/value資料庫儲存服務的註冊資訊,並提供服務例項的變更通知。
Self Registration
優點
- 服務例項能夠更好的掌握註冊時機,僅在真正可提供服務時才註冊到ServiceRegistry
缺點:
- 所有服務都需要實現註冊和取消註冊程式碼,實現複雜且與ServiceRegistry有耦合;
- 服務的例項很容易在不能提供服務時忘記取消註冊;
3rd Party Registration
優點:
- 服務例項不需要負責服務的註冊和取消註冊,實現簡單
- 第三方的服務註冊機制通常會提供健康檢查機制判斷註冊的服務例項是否可用
缺點:
- 第三方的軟體通常也需要進行部署和管理,增加了複雜度
- 第三方的服務註冊機制通常無法瞭解服務例項的實際狀態
服務發現
客戶端要使用服務必須通過服務發現技術獲取服務的位置資訊。服務發現包括買二手手遊賬號地圖Client-Side的服務發現和Server-Side的服務發現兩種方式。
Client-Side Discovery
Client-Side Discovery
在Client-Side Discovery的設計中,服務例項的發現由Client進行,發現的方式可以是主動到ServiceRegistry查詢,也可以由ServiceRegistry通知到Client。在使用Client-Side Discovery時,Client會發現服務的所有例項,並根據LB策略選擇一個例項發起請求。
Server-Side Discovery
Server-Side Discovery
在Server-Side Discovery設計中,在Client和所有的服務例項間增加LoadBalance,Client只需要訪問LoadBalance,由LoadBalance負責服務的發現和負載均衡。
方案對比
不論是Client-Side還是Server-Side的服務發現,執行發現的元件(Client/LoadBalance)通常都需要引入本地快取,並通過核查保證與ServiceRegistry的一致性。引入快取可以避免對ServiceRegistry的頻繁互動,能夠提升效能。
Client-Side Discovery相對於Server-Side Discovery有更少的跳數,效能更優。但所有型別的客戶端都需要實現服務發現與LB演算法,客戶端的複雜度高,且與ServiceRegistry耦合。
Server-Side Discovery設計中,客戶端只需要看到LoadBalance,複雜度低;如果是基於公有云提供服務,則公有云提供商通常會提供現成的服務端LoadBalance。但相對Client-Side Discovery增加了一跳,對效能有一定影響;同時LoadBalance的開發、部署、運維帶來了額外的複雜度;
總結
在服務例項的位置會發生動態變化的微服務架構中,需要引入服務註冊和發現技術。
服務註冊和發現需要一個位置固定或提供了固定域名的ServiceRegistry服務,服務釋出端通過Self-Registration或3rd Party Registration將所有的服務例項註冊到ServiceRegistry,Client或LoadBalance則通過其獲取服務例項的位置以執行負載均衡和傳送服務請求。
ServiceRegistry和LoadBalance是系統中的關鍵服務,如果這兩個服務出現了異常,通常會導致系統不可用,因此它們必須具備極高的可用性。