架構模式: 微服務架構

模式: 微服務架構

背景

在開發服務端企業應用時,應用須要支持各類不一樣類型的客戶端,好比桌面瀏覽器、移動瀏覽器以及原生移動應用。應用還須要向第三方提供可訪問的API,並經過Web Service或者消息代理與其它應用實現集成。應用經過執行業務邏輯、訪問數據庫、與其它系統交換信息、並返回一條HTML/JSON/XML響應,來處理請求(HTTP請求與消息)。html

應用採用多層架構或者六角架構,主要由如下幾類不一樣組件構成:web

  • 展示組件——負責處理HTTP請求並響應HTML或者JSON/XML(對於web Services APIs)
  • 業務邏輯——應用的業務邏輯
  • 數據庫訪問邏輯——用於訪問數據庫的數據訪問對象
  • 應用集成邏輯——消息層,例如基於Spring Integration

不一樣邏輯組件分別響應應用中的不一樣功能模塊。數據庫

問題

應用的部署架構是什麼?編程

需求

  • 應用須要由一個開發者團隊專門負責
  • 團隊新成員須要快速上手
  • 應用應該易於理解和修改
  • 對應用可以進行持續部署
  • 須要在多臺設備上運行應用副本,從而知足可擴展性與可用性的要求
  • 使用各類新技術(框架、編程語言等)

方案

用 Scale Cube 方法(特別是Y軸擴展)設計應用架構,將應用程序按功能拆分爲一組互相協做的服務。每一個服務實現一組特定、相關的功能。舉例來講,一個應用程序可能由訂單管理服務、客戶管理服務等多個服務構成。後端

服務間的通訊則可由HTTP/REST等同步協議或者AMQP等異步協議實現。服務能夠彼此獨立開發與部署。每一個服務皆有本身的數據庫,從而保證其與其它服務解耦。在必要時,可利用數據庫複製機制或者應用層事件驅動機制,維護數據庫之間的數據一致性。瀏覽器

示例

假設須要構建一款電子商務應用程序,使其可以接收來自客戶的訂單、驗證庫存信息與可用信用額度,然後進行發貨。該應用程序會包含多個組件,其中StoreFrontUI負責實現用戶界面,而其它後端服務則分別負責檢查信用額度、維護庫存信息以及發送訂單。服務器

此應用程序被部署爲一組服務集合。
架構

 

結果

優點

此類解決方案擁有如下優點:app

  • 每項微服務相對較小
    • 易於開發者理解
    • IDE處理速度更快,可提升開發者生產效率
    • Web容器啓動速度更快,提升開發者生產效率並可加快部署速度
  • 每項服務皆可獨立於其它服務進行部署——簡化頻繁部署新服務版本的流程
  • 易於實現規模化開發。多團隊能夠共同進行開發工做。每一個(雙披薩,即團隊成員規模控制在訂購兩塊披薩便可吃飽的程度)團隊負責其中一項服務。各團隊可獨立於其餘團隊,進行開發、部署工做及擴展自身服務。
  • 改善故障隔離。舉例來講,若是某一服務出現內存外溢,則只有該服務自己受到影響。其它服務將繼續正常處理請求。相比之下,單體架構中的故障組件會令整套系統陷入癱瘓。
  • 每項服務可獨立進行開發與部署
  • 無需長期使用同一套技術堆棧

弊端:

但這類解決方案中也存在着如下弊端:框架

  • 開發者必須應對建立分佈式系統所產生的額外的複雜因素。
    • 現有開發者工具/IDE主要面向單體應用程序,所以沒法顯式支持分佈式應用的開發。
    • 測試工做更加困難。
    • 開發者必須採起服務間通訊機制。
    • 很難在不使用分佈式事務機制的狀況下跨服務實現功能。
    • 跨服務實現功能要求各團隊進行密切協做。
  • 部署複雜。在生產環境下,對這類多種服務類型構建而成的系統進行部署與管理十分困難。
  • 內存佔用量更高。微服務架構使用N*M個服務實例替代N個單體應用實例,若是每項服務運行本身的JVM(或者其它相似機制),且各實例之間須要進行隔離,那將致使M倍JVM運行時的額外開銷。另外,若是每項服務都在本身的虛擬機(例如 EC2 實例)上運行,如同Netflix同樣,那麼額外開銷會更高。

須要解決的問題

採用微服務架構以前,有若干須要解決的問題。

什麼時候應該使用微服務架構?

應用此類方案帶來的挑戰在於如何把握好時機。在開發應用程序的最第一版本時,你們每每不會面臨須要使用微服務架構才能解決的問題。另外,使用複雜的分佈式架構會拖慢開發流程。對於初創企業,其面臨的最大挑戰每每在於如何快速發展商業模式及附屬應用。微服務架構中的Y軸拆分方式可能使應用更加難以迅速迭代。可是,若是當面臨須要解決擴展性問題的時候再去進行功能拆分,單體應用的複雜依賴性使其很難被分解爲服務集合。

如何將應用拆分爲服務?

另外一項挑戰在於如何將系統拆分爲多個微服務。這雖然很棘手但仍是有些可行之策:

  • 根據業務能力拆分(Decompose by business capability) - 根據業務能力界定服務的範圍
  • 根據領域的子域拆分(Decompose by subdomain) - 根據領域驅動設計中子域的概念界定服務的範圍
  • 根據「動詞」或者用例進行服務劃分。舉例來講,咱們常常會在電子商務應用中發現有單獨的「發貨」服務用於處理已完成訂單。另外一種常見的「動詞」劃分方式是實現登陸用例的「登陸」服務。
  • 根據「名詞」或者資源進行系統劃分。這類服務負責利用特定的實體/資源完成一系列操做。舉例來講,你們可能會在電子商務系統當中發現有「庫存」服務用於跟蹤貨物的庫存。

在理想狀況下,每項服務都應只面向一小部分職責。(大叔)Bob Martin 曾提出根據單一責任原則(Single Responsibility Principle,簡稱 SRP)進行類的設計。SRP 會用單一變動理由去定義一個類的職責:一個類的狀態變動只能由一個緣由致使。同理,咱們也能夠在微服務設計當中引入 SRP。

另外一項可用於指導服務設計的是Unix工具的設計思路。Unix 提供大量工具選項,包括 grep、cat 以及 find 等等。每種工具都只負責實現一項功能,並且功能良好,它們能夠經過Shell腳本與其它工具結合進而執行復雜的任務。

如何維護數據一致性?

爲了確保鬆耦合,每一個服務都有獨用的數據庫。維護服務間的數據一致性成爲了挑戰。在多數應用的架構下,2 階段提交和分佈式事務再也不是一個可選項。應用須要採用事件驅動架構,一個服務在其數據發生變化時,對外發佈一個事件,其餘服務訂閱並經過消費這個事件來對應更新本身的數據。有一些可靠的方式能夠實現事件的發佈和數據的更新,好比事件溯源 和事物日誌跟蹤。

如何實現數據查詢?

另外一個挑戰是進行跨服務的數據的查詢。一個經常使用的解決方式是採用CQRS,維護一份包含重要數據的視圖並經過事件流的方式保持數據的更新。

相關模式

微服務架構有不少與之相關的模式,單體架構 即是微服務架構的另外一衆選擇。在應用微服務架構時,您還會跟以下這些模式打交道:

 

  • 服務拆分模式
    • 根據業務能力拆分
    • 根據領域的子域拆分
  • 每服務數據庫模式 描述了服務之間採用獨享數據庫的方式實現瞭解耦合。
  • API 網關模式 定義在微服務架構下客戶端訪問服務的方式。
  • 客戶端服務發現 和 服務器端服務發現 模式用來在微服務架構中把客戶端請求路由到一個可用的服務實例上。
  • 消息和遠程過程調用是服務間通訊的兩種選擇。
  • 單主機上部署服務的單個實例 和 單主機上部署服務的多個實例 模式是兩種不一樣的部署策略。
  • 解決邊界問題的模式:: 微服務的基底模式 和 配置信息外部化
  • 可測試性模式: 服務組件測試 和 服務集成協議測試
  • 斷路器
  • 訪問令牌
  • 可觀測性模式:
    • 應用日誌
    • 應用指標
    • 審計日誌
    • 分佈式追蹤
    • 異常追蹤
    • 健康檢查
  • UI 模式:
    • 服務器端頁面碎片化元素構建
    • 客戶端 UI 構建

已知案例

衆多大型網站將單體架構發展爲微服務架構,其中包括 NetflixAmazoneBay 等。

做爲一個熱門視頻流服務,Netflix 利用一套大規模的面向服務的架構來承載高於 30% 的互聯網流量。該公司天天須要處理來自 800 多種設備的 10 億屢次視頻流 API 請求。平均每次 API 調用會在後端服務中產生 6 次後續調用。

Amazon.com 最初採用一套雙層架構。爲了擴展業務規模,其決定遷移至一套由數百項後端服務構成的面向服務的架構。多個應用調用這些服務,其中包括 Amazon.com網站和Web服務API。Amazon.com 網站須要調用 100 到 150 個服務方可獲取到構建一個 Web 頁面所需的所有數據。

做爲拍賣網站,eBay.com 也是從單體架構逐步轉向面向服務的架構。其應用層由多個獨立應用構成。每一個應用負責實現完成一組特定功能的業務邏輯,例如購買或者出售。每一個應用皆利用X軸進行拆分,部分應用(例如搜索)以Z軸進行拆分。eBay.com 還在數據庫層採用了 X、Y 與 Z 軸相結合的擴展方式。

相關文章
相關標籤/搜索