架構師也需要掌握的微服務架構設計指南

架構師也需要掌握的微服務架構設計指南

將某個單一功能的應用單元分解成多個微型服務單元,這就是微服務處置傳統單體式架構的思想。

但是,實際上微服務的架構模式遠不止這麼一種。如今,它已經成為了各大主流軟件的首選開發方案。

微服務在提高系統整體性能的同時,也存在著一些自身的侷限性。因此對於一名架構設計師來說,他需要掌握各種微服務設計模式的特點和應用範圍。

下面,在我們開始深入探究之前,先簡單回顧一下微服務架構的基本概念和整體功能。

微服務架構的設計原則

微服務架構的設計原則如下:

  • 高內聚、低耦合。
  • 無縫的 API 集成。
  • 為每一項服務分配唯一的資源標識。
  • 實時流量管理。
  • 最小化數據表,以優化加載。
  • 通過內/外部 API,執行持續監控。
  • 為每個微服務隔離數據的存儲。這對於限制數據的訪問和避免“服務的耦合”是非常有用的。

例如:基於用戶的分類數據,我們可以實施命令查詢的責任分離(Command Query Responsibility Segregation,CQRS)。

  • 去中心化。設計微服務架構的首要原則是:將單體結構分解成獨立的多個實體,而這些實體就被稱為微服務。

這些微服務能夠獨立於其他的系統功能提供服務,用戶對它們採取的所有編輯、刪除、或在其他地方的使用,都不會影響到本系統的整體性能。

  • 可擴展性。微服務的設計目標是:性能與效率。在現實世界中,解決大型系統的可擴展性問題,是任何微服務生態系統的性能體現。

雖然豐富的技術功能給大量的數據工作帶來了多種數據片段,但是如果能恰當地實施、並使用各種應用程序控制器(Application Controllers),則會讓微服務架構更具可擴展性。

  • 通過與 DevOps 的集成,實現持續交付。DevOps 的多技術互通與融合,比較適合於微服務架構。在設計微服務架構時,我們需要關注性能和系統效率的提升,這正好契合了 DevOps 的更快交付出方案的理念。

相對於傳統的單體式設計,它更適合於部署性、可靠的和可擴展性的方案管理。

當然,相對於上述各項原則與優勢,微服務架構也有著一定的侷限性。不過好在我們擁有多種微服務的設計模式可供選擇,來實現自己的系統設計目標。下面讓我們來逐一進行討論。

針對有效協作的微服務設計模式

高效的微服務架構必須能夠讓多個微服務實現有效的協作和同步運行。

聚合器微服務設計模式

由於會涉及到多種業務,我們有必要為最終用戶截獲輸出、並將其予以合併。

對於用戶來說,如果他們想自行合併數據,則需要具有對於系統的大量內部知識。

那麼,我們在設計微服務架構時,為了打破這種單體性,就應當根據輸出來進行資源的劃分。因此,我們利用聚合器模式,來彙總這些數據。

這種方案可以通過兩個主要組件,來呈現給最終用戶。其中的一種是帶有 API 網關的複合式微服務。它可以彙總數據,並將其轉發給用戶。

如果您需要在分解的系統中用到各種業務功能模塊的話,複合式微服務應當成為您的首選。

分支微服務設計模式

此模式擴展了聚合器的設計模式。在分支模式下,您可以通過兩個獨立的(更精確地說是:互斥的)微服務鏈,來同時處理請求和響應。

這種設計模式能夠根據您的不同業務需求,為單個或多個服務鏈提供靈活性。

例如:針對某個電子商務網站或 Web 應用程序,我們可能按需接收來自不同微服務的多個數據源。

後端為前端/API 網關

從每個運行服務處獲取數據,是任何應用程序的首要任務。對於微服務架構而言,從獨立的服務中提取數據,同樣非常重要。

但是,僅通過一個用戶界面(UI),從大量的微服務中獲取用戶手中的資源信息,並不是一件容易的事。

因此,就像企業裡的服務檯那樣,我們可以在微服務架構中,用 API 網關來為所有的交互操作提供統一的入口。

另外,在安全方面,API 網關也有助於實現用戶的授權、和為合適的用戶提供相關的 API。

因此 API 網關作為單一的切入點,不僅能夠充當代理服務器的作用,將各種請求路由到不同的微服務那裡,還能彙總來自多個服務的輸出結果,併發送給用戶。

它可以處理多種協議請求,並按需進行轉換(例如,實現 HTTPS 與 AMQP 之間的互轉)。

針對性能監控的微服務設計模式

性能監測是確保微服務架構成功的另一個重要方面。它有助於衡量系統的效率,並獲悉拖慢系統的罪魁禍首。下列模式涉及到可觀測性的範疇,能夠保障微服務架構設計的魯棒性。

日誌聚合

微服務是可以獨立地、並行地支持多種其他服務的。而且,它的實例能夠橫跨各臺機器。

同時,每個服務都會根據其執行情況生成一個日誌入口。那麼我們該如何跟蹤這些大量的服務相關日誌呢?

這正是日誌聚合模式的切入點。為了防止出現混亂的局面,我們應當設置一個可以對所有微服務實例進行日誌聚合的主服務。而且,這種集中式日誌應當具有搜索和監控的功能。

綜合監控(或稱語義監控)

對微服務架構的監控,是一項繁瑣、但又必要的任務。當有數百個服務同時運行時,要想在日誌庫裡查明某個失敗的根本原因,那就更難了。此時,綜合監控可能會派上用場。

在您進行自動化測試時,綜合監控能夠幫助您將結果與生產環境定期進行映射和比較。一旦出現故障,用戶將及時得到相關警告。

另外,語義監控還能幫助您實現如下兩方面:

  • 監測自動化的測試案例。
  • 根據業務需求,檢測生產環境中的故障。

同時,隨著系統的負載和微服務數量的增加,對系統性能的持續監控,並跨服務發現潛在的問題,就顯得非常重要了。

我們可以通過指標服務(metric service)來收集各類數據。指標服務可以是“推式”和“拉式”兩種形式。

顧名思義,推式服務(如:AppDynamics)是將捕捉到的數據指標推送到服務端;而拉式服務(如:Prometheus)則負責從服務中拉取對應的數據指標。

API 健康檢查

微服務架構的設計促進了各個服務之間的相互獨立,並避免了系統中的任何延遲。

我們知道,API 在網絡連接中能夠起到基石作用。我們需要通過對 API 的定期健康檢查,來提前發現各種障礙。

例如,您可能會經常觀察到:某個微服務雖然處於啟動和和運行狀態,卻沒有能力去處理任何請求。

那麼,以下便是一些導致 API 故障的因素:

  • 服務器的負載
  • 用戶的使用量
  • 各種延遲
  • 錯誤日誌
  • 下載量

為了應對上述因素,我們應該確保每一個服務在運行時,都配有一個健康檢查的特定 API 端點。

例如:我們可以在每個服務的末尾,通過追加 HTTP/health 的參數,以返回各個服務實例、主機、連接和算法邏輯等方面的健康狀況。

同時,服務註冊中心需要定期調用健康檢查的 API 端點,以執行相關的健康掃描任務。

而健康檢查的內容則可以包括如下方面:

  • 針對特定應用的系統邏輯。
  • 主機的狀態。
  • 連接到其他基礎設施或任何服務實例的連接狀態。

為業務能力而改變一切

在將單體架構分解成多個微服務的過程中,我們需要根據實際情況遵循不同的設計模式。

針對業務能力的獨特微服務

微服務的成功應該能夠充分體現高內聚和低耦合的特點。因此各種服務需要在抽象出相似功能的基礎上,保持低耦合的狀態。那麼,我們該如何將軟件系統分解成為更小、更獨立的邏輯單元呢?

我們需要定義微服務的範圍,從而支持特定的業務能力。例如,我們可以將組織的內部架構分為技術、營銷、公關、銷售、服務和運維等不同部門,這些不同的職能部門都可以被看作是各個微服務,而組織本身就是一套系統。

因此,為了保持效率和預估增長,我們需要按照業務能力對系統進行分解,基於各種能力所產生的價值,區分不同的業務領域。

圍繞相似業務能力的微服務

雖然我們可以按照業務能力分類出各種微服務,但是我們該如何處置那些服務中的通用類呢?在此,我們可以用需要干預的“神類(God Classes)”來分解這些類。

例如,在電子商務系統中,訂單是一個共用類,一些諸如訂單號、訂單管理、訂單退貨、訂單交付等服務都會用到它。因此針對該問題,我們引入了領域驅動設計(Domain-Driven Design,DDD)的微服務設計原則。

在領域驅動設計中,我們使用到了各個子域。這些子域模型應當被預定好功能的範圍,即界限上下文(bounded context)。

這些界限上下文作為參數被用來創建微服務,從而克服了通用類的相關問題。

刀砍藤蔓的模式

上面我們討論了對全新單體架構概念的分解,下面我們來看看如何將現有的單體系統轉換為微服務架構。在此,我們引入刀砍蔓藤的模式。

由於在 Web 應用中,經常會涉及到不同域裡各個服務之間的往返調用,因此刀砍模式非常適用於對域的切分。

在該模式下,雖然系統會出現兩個域共用一個相同 URI 的情況,但是一旦某個服務完成了轉換,我們就會砍掉其對應的應用程序中的現有版本。而且,此過程會一直持續下去,直到單體系統不復存在為止。

針對優化數據庫存儲的微服務設計模式

就微服務架構而言,其松耦合的特性造就了各個獨立服務的部署與擴展能力。

但是由於不同的服務有著不同的存儲需求,因此它們可能需要訪問那些並非存儲在本地的數據。

下面讓我們來討論一些根據不同的需求,所適合採用的主要數據庫設計模式。

基於服務的單獨數據庫

在領域驅動設計的原則中,基於服務的單獨數據庫,是將整個數據庫分配給特定的微服務。

因此,我們需要按照服務來事先設計好獨享的數據庫。也就是說,任何其他的外部微服務都無法訪問,其他未分配給自己的數據庫裡的數據,除非是通過微服務的 API 網關方式。

基於服務的共享數據庫

如果我們只是將上述獨享數據庫模式運用到,將單體架構分解成多個微服務的場景中,那麼難免會碰到各種麻煩。

因此,我們可以在分解的過程中,對有限數量的服務採用基於服務的共享數據庫模式。

而這個數量一般會被限制在 2~3 個,否則對系統的部署、自治性和擴展性有所影響。

事件溯源式設計模式

當應用的當前狀態發生變化時,我們如何才能確保架構能夠按需變更,並根據這些變更實時地產生相應的事件呢?

事件溯源(Event Sourcing)模式,能夠根據每個業務實體的狀態變化,順次將新的事件追加到事件列表之中。

在系統中,諸如 Customer 這樣的實體會產生許多事件,因此我們可以對實體的當時狀態進行“截屏式”事件錄入,以便進一步查詢或通過自動化的狀態調整,來優化負載。

命令查詢的責任分離(CQRS)

對於基於服務的數據庫模式而言,由於訪問被限制在了單個數據庫之中,因此我們很難達到各種複雜的查詢效果。那麼我們該如何實現各種基於數據庫系統的聯合查詢呢?

CQRS 模型將單個應用程序分為命令和查詢兩個部分:

  • 命令部分處理各種創建、更新和刪除之類的請求。
  • 查詢則用到了物化視圖(materialized view),而這些視圖是通過事件流來進行更新的。

同時,這些事件又是由事件溯源模式所產生,並標註了數據中的各種變化。

針對無縫部署的微服務設計模式

在我們實施微服務時,難免會在服務的調用上碰到問題,因此我們可以採用橫切(cross-cutting)的模式來簡化工作。

服務發現

由於採用了容器技術,IP 地址往往是被動態地分配的。這就意味著 IP 地址會隨時發生改變,進而導致服務的中斷。此外,用戶需要記住每個服務的 URL,而這反而倒退成了緊耦合狀態。

為了解決該問題,我們需要通過一個註冊表,向用戶的請求提供位置信息。服務實例在啟動時,能夠被註冊到表中;而在關閉時,也能被註銷。

此法有助於用戶找出那些可用來查詢的準確位置。此外,註冊表通過健康檢查,能夠確保實例的可用性,進而提高系統的性能。

藍-綠部署

在微服務架構中,一個系統裡往往有著多個微服務。如果我們因為部署、或更新版本而停止所有的服務的話,那麼長時間的停機勢必會影響整體的生產力。

因此,我們需要在設計微服務架構時,通過藍-綠部署的模式,來避免該問題。

在這個模式中,我們同時有著藍、綠兩套相同且並行的環境。在任一時間點,只有一套環境(如藍色系統)真實在線,並處理著真實的業務流量。

那麼在需要進行新的部署時,我們將應用的最新版本上傳到綠色系統中,並將真實對外的路由器切換到綠色系統上,以完成更新。

結論

雖然您不一定會在自己的微服務系統中用到上述每一種設計模式,但是這些模式都有著它們獨特的應用場景。

作為架構師,對於不同的微服務架構設計模式,您需要從應用的設計階段到生產環境的維護階段,持續進行各種評估、審計、測試和實踐。相信它們在給您帶來一致性標準的同時,也能提高您的應用的整體可靠性。


分享到:


相關文章: