當我們在系統範圍內部署大量的微服務時,一個新的挑戰產生了,單體應用部署時不會發生。這篇文章將針對這些新的挑戰,在系統範圍內部署大量微服務時定義一套操作模型(operations model)。這篇文章分為如下幾個部分: 前提條件;擴展;問題;需要的組件;參考模型;下一步; ...
這裡並不是介紹微服務概念,如需要瞭解微服務,可以閱讀Fowler-Microservices文章。本博客假定我們已開始使用微服務解耦單體應用,用來提升可部署性和可擴展性。
當我們在系統範圍內部署大量的微服務時,一個新的挑戰產生了,單體應用部署時不會發生。這篇文章將針對這些新的挑戰,在系統範圍內部署大量微服務時定義一套操作模型(operations model)。
這篇文章分為如下幾個部分:
- 前提條件;
- 擴展;
- 問題;
- 需要的組件;
- 參考模型;
- 下一步;
1. 前提條件
當在系統範圍內需要部署大量微服務時,需要什麼條件呢?
根據Flower的文章,如下是我們想要得到的:
(Source:http://martinfowler.com/articles/microservices.html)
然而,在開始發佈大量微服務替換單體應用之前,我們需要實現如下這些前置條件:
- 目標架構;
- 持續交付工具;
- 合適的組件結構;
下麵簡要描述每一個前置條件。
1.1 目標架構
首先,我們需要分區微服務。例如,我們可以垂直分解微服務。
- 核心服務(Core services)-處理業務數據的持久化和實施業務邏輯和其他規則;
- 組合服務(Composite services)-組合服務指編排一組核心服務實現一個特定任務,或者從一組核心服務中聚合信息;
- API services – 向外暴露功能,例如允許第三方使用底層功能創建新的應用;
也可以水平上應用領域驅動分解。如下是一個目標架構:
備註:這僅僅是一個範例目標架構,你可以使用完全不同的架構。核心時在開始部署微服務之前,需要有簡歷一個目標架構。否則,你最終的架構有可能像一團麵條一樣,甚至比現有的單體應用更加糟糕。
1.2 持續交付
我們假定已經有了一套可持續交付的發佈工具,以便我們可以高效地反覆發佈微服務。
(Source: http://www.infoq.com/minibooks/emag-devops-toolchain)
1.3合適的組織
最後,我們需要採用合適的組織結構,避免和Conway法則相衝突。Conway法則如下:
Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization’s communication structure.
(Source: http://martinfowler.com/articles/microservices.html)
2. 擴展
接下來是本文關註的要點:
當我們分解單體應用,並使用大量的微服務替換時,在系統範圍內會發生什麼呢?
(1) 大量的部署單元
將產生需要的小的微服務,而不是之前的一個大的單體應用,這將需要管理和跟蹤大量的部署單元。
(2) 微服務將同時暴露和調用服務
在系統範圍內,大部分的微服務彼此是互相連接的。
(3) 一些微服務暴露外部API
這些微服務將負責包含其他的微服務不允許外部訪問。
(4) 系統根據動態
新的微服務部署,替換老的服務。現有的微服務新增實例,滿足增長的負荷。這意味著微服務將比以前更高的頻率增加和下線。
(5) 平均故障時間(MTBF)將下降
在系統範圍內,故障發生頻率將更頻繁。軟體組件將不時發生問題。大量部署的微服務將比之前部署的單體應用出現問題的可能更高。
3. 問題
微服務模型將導致一些重要的運行時相關的問題:
(1) 微服務如何配置以及是否正確?
針對少量的應用程式,處理配置不是主要的問題,如使用配置文件或者在資料庫中的配置表。在大量的微服務部署到大量的伺服器上時,這一配置訪問將變得非常複雜。這將導致大量的小的配置文件或者數據配置表遍佈整個系統,使得難以高效可靠地維護。
(2) 什麼微服務部署了,部署在哪裡了?
在只有少量服務部署時,管理部署的主機和埠還是比較簡單的。但是當有大量的微服務部署時,這些服務或多或少需要持續變更,如手工維護將變得非常麻煩。
(3) 如何維護路由信息?
在動態系統範圍中,服務消費方也是一個挑戰。尤其是路由表或者消費配置文件,需要手工更新。在微服務不斷新增新的主機/埠時,將沒有時間手工維護。交付時間將會延長,並且手工維護出錯的風險也會增加。
(4) 如何防止失敗鏈?
由於微服務之間是相互連接的,需要關註系統範圍內的失敗鏈。例如,一個被其他眾多微服務依賴的微服務失敗了,其他依賴的微服務也可能開始失敗。如果沒有合適處理,大量微服務將受到這個單一失敗的微服務所影響,導致一個脆弱的系統。
(5) 如何驗證所有的微服務已上線且在運行中?
跟蹤少量應用的運行狀態是比較簡單的,但是如何驗證所有的微服務是健康的,且準備好接收請求?
(6) 如何跟蹤服務之間的消息?
如何應對組織開始接到關於一些流程執行失敗?什麼微服務到導致這一問題的根本原因?例如,訂單12345卡住了,我們如何知道是因為微服務A無法訪問,還是因為微服務B在發送一個訂單確認消息之前,需要手工批准。
(7) 如何確保僅僅API服務暴露給外部?
例如我們如何避免外部未授權的請求,對內部微服務的訪問?
(8) 如何保證API服務的安全?
這不是針對微服務的特定問題,但是保護對外暴露的微服務仍然是非常重要的。
4. 需要的組件
為瞭解決上述的一些問題,新的操作和管理功能是必須的。針對上述問題,建議的解決方案包括如下組件:
(1) 中心配置服務Central Configuration Server
我們需要一個中心配置管理,而不是針對每一個部署單元(微服務)有一個本地配置。此外,我們還需一個配置API,微服務用來獲取配置信息。
(2) 服務發現服務 Service Discovery Server
我們需要服務發現功能,微服務在啟動時,通過API自己註冊,而不是手工跟蹤微服務部署的主機和埠。
(3) 動態路由和負載均衡 Dynamic Routing and Load Balancer
基於服務發現功能,路由組件使用discovery API 查詢請求的微服務部署在哪裡;在被請求的服務部署了多個實例的情況下,負載均衡組件可以決定路由請求到特定的實例。
(4) 電路斷路器 Circuit Breaker
為了避免失敗鏈問題,我們需要營養Circuit Breaker模式,詳細信息可以參考 Fowler-Circuit Breaker的文章。
(5) 監控 Monitoring
基於電路斷路器,我們可以監控微服務的狀態,同時收集運行時統計數據,獲知服務的健康狀態和當前使用率。這些信息可以收集並顯示在dashboard上,並針對配置閾值設置自動報警。
(6) 中心日誌分析 Centralized Log Analysis
為了跟蹤消息,並檢測微服務何時故障,我們需要一個中心日誌分析功能,可以訪問伺服器並收集每一個微服務的log文件。日誌分析功能保存log信息在中心資料庫中,並提供了查詢和dashboard功能。備註:為了查找相關的消息,所有微服務需要在log消息中使用相關的id,這點很重要。
(7) 邊緣服務 Edge Server
為了對外部暴露API 服務,並阻止對內部微服務的未授權訪問,我們需要一個邊緣服務(Edge Server),所有外部的訪問都經過邊緣伺服器。基於前面的服務發現組件,邊緣伺服器可以重用動態路由和負載均衡功能。邊緣伺服器作為一個動態和有效的反向代理,在內部系統更新時,不必手動更新。
(8) OAuth 2.0保護的API
建議OAuth 2.0 標準保護暴露的API服務。應用OAuth 2.0 有如下效果:
1/一個新組建作為OAuth Authorization Server;
2/API服務作為OAuth Resource Server;
3/外部API消費方作為OAuth Clients;
4/邊緣伺服器(Edge Server)作為OAuth Token Relay;
(4.1)作為OAuth Resource Server;
(4.2)將外部請求中的OAuth Access Tokens傳遞給API 服務;
備註:OAuth 2.0 標準可能通過OpenID Connect標準來補充完善,提供更好的授權功能。
5. 參考模型
總而言之,微服務需要一套包含上述支持服務的基礎設施,微服務使用它們的API來交互。下圖描繪了這一基礎設施:
備註:為了減少上圖中交互的複雜度,微服務和支持服務的交互並沒有畫出來。
6. 下一步
在接下來的文章中,我們將描述和演示如何實現上述建議的參考模型。
英文原文鏈接:
An operations model for Microservices