如何快速搭建一個微服務架構

什麼是微服務?java

微服務(Microservices Architecture)是一種架構風格,一個大型複雜軟件應用由一個或多個微服務組成。系統中的各個微服務可被獨立部署,各個微服務之間是鬆耦合的。每一個微服務僅關注於完成一件任務並很好地完成該任務。在全部狀況下,每一個任務表明着一個小的業務能力。web

微服務的概念源於2014年3月Martin Fowler所寫的文章「Microservices」 martinfowler.com/articles/mi…spring

單體架構(Monolithic Architecture )數據庫

企業級的應用通常都會面臨各類各樣的業務需求,而常見的方式是把大量功能堆積到同一個單體架構中去。好比:常見的ERP、CRM等系統都以單體架構的方式運行,同時因爲提供了大量的業務功能,隨着功能的升級,整個研發、發佈、定位問題,擴展,升級這樣一個「怪物」系統會變得愈來愈困難。編程

這種架構模式就是把應用總體打包部署,具體的樣式依賴自己應用採用的語言,若是採用java語言,天然你會打包成war包,部署在Tomcat或者Jetty這樣的應用服務器上,若是你使用spring boot還能夠打包成jar包部署。其餘還有Rails和Node.js應用以目錄層次的形式打包設計模式

clipboard.png

上圖:單體架構安全

大部分企業經過SOA來解決上述問題,SOA的思路是把應用中相近的功能聚合到一塊兒,以服務的形式提供出去。所以基於SOA架構的應用能夠理解爲一批服務的組合。SOA帶來的問題是,引入了大量的服務、消息格式定義和規範。服務器

多數狀況下,SOA的服務直接相互獨立,可是部署在同一個運行環境中(相似於一個Tomcat實例下,運行了不少web應用)。和單體架構相似,隨着業務功能的增多SOA的服務會變得愈來愈複雜,本質上看沒有由於使用SOA而變的更好。圖1,是一個包含多種服務的在線零售網站,全部的服務部署在一個運行環境中,是一個典型的單體架構。網絡

單體架構的應用通常有如下特色:架構

  • 設計、開發、部署爲一個單獨的單元。
  • 會變得愈來愈複雜,最後致使維護、升級、新增功能變得異常困難
  • 很難以敏捷研發模式進行開發和發佈
  • 部分更新,都須要從新部署整個應用
  • 水平擴展:必須以應用爲單位進行擴展,在資源需求有衝突時擴展變得比較困難(部分服務須要更多的計算資源,部分須要更多內存資源)

可用性:一個服務的不穩定會致使整個應用出問題

  • 創新困難:很難引入新的技術和框架,全部的功能都構建在同質的框架之上
  • 運維困難:變動或升級的影響分析困難,任何一個小修改均可能致使單體應用總體運行出現故障。

微服務架構(Microservices Architecture)

微服務架構的核心思想是,一個應用是由多個小的、相互獨立的、微服務組成,這些服務運行在本身的進程中,開發和發佈都沒有依賴。不一樣服務經過一些輕量級交互機制來通訊,例如 RPC、HTTP 等,服務可獨立擴展伸縮,每一個服務定義了明確的邊界,不一樣的服務甚至能夠採用不一樣的編程語言來實現,由獨立的團隊來維護。簡單的來講,一個系統的不一樣模塊轉變成不一樣的服務!並且服務可使用不一樣的技術加以實現!

clipboard.png

上圖:微服務架構

微服務設計

那咱們在微服務中應該怎樣設計呢。如下是微服務的設計指南:

  • 職責單一原則(Single Responsibility Principle):把某一個微服務的功能聚焦在特定業務或者有限的範圍內會有助於敏捷開發和服務的發佈。
  • 設計階段就須要把業務範圍進行界定。
  • 須要關心微服務的業務範圍,而不是服務的數量和規模儘可能小。數量和規模須要依照業務功能而定。
  • 於SOA不一樣,某個微服務的功能、操做和消息協議儘可能簡單。
  • 項目初期把服務的範圍制定相對寬泛,隨着深刻,進一步重構服務,細分微服務是個很好的作法。

微服務消息

在單體架構中,不一樣功能之間通訊經過方法調用,或者跨語言通訊。SOA下降了這種語言直接的耦合度,採用基於SOAP協議的web服務。這種web服務的功能和消息體定義都十分複雜,微服務須要更輕量的機制。

同步消息 REST

同步消息就是客戶端須要保持等待,直到服務器返回應答。REST是微服務中默認的同步消息方式,它提供了基於HTTP協議和資源API風格的簡單消息格式,多數微服務都採用這種方式(每一個功能表明瞭一個資源和對應的操做)

異步消息 – AMQP, STOMP, MQTT

異步消息就是客戶端不須要一直等待服務應答,有應到後會獲得通知。某些微服務須要用到異步消息,通常採用AMQP, STOMP, MQTT 這三種通信協議

消息格式 – JSON, XML, Thrift, ProtoBuf, Avro

消息格式是微服務中另一個很重要的因素。SOA的web服務通常採用文本消息,基於複雜的消息格式(SOAP)和消息定義(xsd)。微服務採用簡單的文本協議JSON和XML,基於HTTP的資源API風格。若是須要二進制,經過用到Thrift, ProtoBuf, Avro。

服務約定 – 定義接口 – Swagger, RAML, Thrift IDL

若是把功能實現爲服務,併發布,須要定義一套約定。單體架構中,SOA採用WSDL,WSDL過於複雜而且和SOAP緊耦合,不適合微服務。

REST設計的微服務,一般採用Swagger和RAML定義約定。

對於不是基於REST設計的微服務,好比Thrift,一般採用IDL(Interface Definition Languages),好比Thrift IDL。

微服務集成 (服務間通訊)

大部分微服務基於RPC、HTTP、JSON這樣的標準協議,集成不一樣標準和格式變的再也不重要。另一個選擇是採用輕量級的消息總線或者網關,有路由功能,沒有複雜的業務邏輯。下面就介紹幾種常見的架構方式。

點對點方式

點對點方式中,服務之間直接用。每一個微服務都開放REST API,而且調用其它微服務的接口。

clipboard.png

上圖:經過點對點方式通訊

很明顯,在比較簡單的微服務應用場景下,這種方式還可行,隨着應用複雜度的提高,會變得愈來愈不可維護。這點有些相似SOA的ESB,儘可能不採用點對點的集成方式。

API-網關方式

API網關方式的核心要點是,全部的客戶端和消費端都經過統一的網關接入微服務,在網關層處理全部的非業務功能個。一般,網關也是提供REST/HTTP的訪問API。服務端經過API-GW註冊和管理服務。

clipboard.png

上圖:經過API-網關暴露微服務

全部的業務接口經過API網關暴露,是全部客戶端接口的惟一入口。微服務之間的通訊也經過API網關。

採用網關方式有以下優點:

  • 有能力爲微服務接口提供網關層次的抽象。好比:微服務的接口能夠各類各樣,在網關層,能夠對外暴露統一的規範接口。
  • 輕量的消息路由、格式轉換。
  • 統一控制安全、監控、限流等非業務功能。
  • 每一個微服務會變得更加輕量,非業務功能個都在網關層統一處理,微服務只須要關注業務邏輯

目前,API網關方式應該是微服務架構中應用最普遍的設計模式。

消息代理方式

微服務也能夠集成在異步的場景下,經過隊列和訂閱主題,實現消息的發佈和訂閱。一個微服務能夠是消息的發佈者,把消息經過異步的方式發送到隊列或者訂閱主題下。做爲消費者的微服務能夠從隊列或者主題共獲取消息。經過消息中間件把服務之間的直接調用解耦。

如何快速搭建一個微服務架構
上圖:異步通訊方式

一般異步的生產者/消費者模式,經過AMQP, STOMP, MQTT 等異步消息通信協議規範。

數據的去中心化

單體架構中,不一樣功能的服務模塊都把數據存儲在某個中心數據庫中。

clipboard.png

每一個微服務有本身私有的數據庫,其它微服務不能直接訪問。單體架構,用一個數據庫存儲全部數據

微服務方式,多個服務之間的設計相互獨立,數據也應該相互獨立(好比,某個微服務的數據庫結構定義方式改變,可能會中斷其它服務)。所以,每一個微服務都應該有本身的數據庫。

clipboard.png

每一個微服務有本身私有的數據庫,其它微服務不能直接訪問。每一個微服務有本身私有的數據庫,其它微服務不能直接訪問。

數據去中心話的核心要點:

  • 每一個微服務有本身私有的數據庫持久化業務數據
  • 每一個微服務只能訪問本身的數據庫,而不能訪問其它服務的數據庫
  • 某些業務場景下,須要在一個事務中更新多個數據庫。這種狀況也不能直接訪問其它微服務的數據庫,而是經過對於微服務進行操做。

數據的去中心化,進一步下降了微服務之間的耦合度,不一樣服務能夠採用不一樣的數據庫技術(SQL、NoSQL等)。在複雜的業務場景下,若是包含多個微服務,一般在客戶端或者中間層(網關)處理。

微服務架構的優勢:

  • 每一個服務都比較簡單,只關注於一個業務功能。
  • 微服務架構方式是鬆耦合的,能夠提供更高的靈活性。
  • 微服務可經過最佳及最合適的不一樣的編程語言與工具進行開發,可以作到有的放矢地解決針對性問題。
  • 每一個微服務可由不一樣團隊獨立開發,互不影響,加快推出市場的速度。
  • 微服務架構是持續交付(CD)的巨大推進力,容許在頻繁發佈不一樣服務的同時保持系統其餘部分的可用性和穩定性。

微服務架構的缺點:

微服務的一些想法在實踐上是好的,但當總體實現時也會呈現出其複雜性。

  • 運維開銷及成本增長:總體應用可能只需部署至一小片應用服務區集羣,而微服務架構可能變成須要構建/測試/部署/運行數十個獨立的服務,並可能須要支持多種語言和環境。這致使一個總體式系統若是由20個微服務組成,可能須要40~60個進程。
  • 必須有堅實的DevOps開發運維一體化技能:開發人員須要熟知運維與投產環境,開發人員也須要掌握必要的數據存儲技術如NoSQL,具備較強DevOps技能的人員比較稀缺,會帶來招聘人才方面的挑戰。
  • 隱式接口及接口匹配問題:把系統分爲多個協做組件後會產生新的接口,這意味着簡單的交叉變化可能須要改變許多組件,並需協調一塊兒發佈。在實際環境中,一個新品發佈可能被迫同時發佈大量服務,因爲集成點的大量增長,微服務架構會有更高的發佈風險。

代碼重複:某些底層功能須要被多個服務所用,爲了不將「同步耦合引入到系統中」,有時須要向不一樣服務添加一些代碼,這就會致使代碼重複。

  • 分佈式系統的複雜性:做爲一種分佈式系統,微服務引入了複雜性和其餘若干問題,例如網絡延遲、容錯性、消息序列化、不可靠的網絡、異步機制、版本化、差別化的工做負載等,開發人員須要考慮以上的分佈式系統問題。
  • 異步機制:微服務每每使用異步編程、消息與並行機制,若是應用存在跨微服務的事務性處理,事務的實現更具挑戰性,其實現機制會變得複雜化。
  • 可測性的挑戰:在動態環境下服務間的交互會產生很是微妙的行爲,難以可視化及全面測試。經典微服務每每不過重視測試,更多的是經過監控發現生產環境的異常,進而快速回滾或採起其餘必要的行動。但對於特別在乎風險規避監管或投產環境錯誤會產生顯著影響的場景下須要特別注意。

關於微服務架構的取捨

  • 在合適的項目,合適的團隊,採用微服務架構收益會大於成本。
  • 微服務架構有不少吸引人的地方,但在擁抱微服務以前,也須要認清它所帶來的挑戰。
  • 須要避免爲了「微服務」而「微服務」。
  • 微服務架構引入策略 – 對傳統企業而言,開始時能夠考慮引入部分合適的微服務架構原則對已有系統進行改造或新建微服務應用,逐步探索及積累微服務架構經驗,而非全盤實施微服務架構。
相關文章
相關標籤/搜索