微服務架構 - 設計總結

目錄如下:

一、微服務架構介紹

二、出現和發展

三、傳統開發模式和微服務的區別

四、微服務的具體特徵

五、SOA 和微服務的區別

六、如何具體實踐微服務

七、常見的微服務設計模式和應用

八、微服務的優點和缺點

九、思考:意識的轉變

十、參考資料和推薦閱讀

一、微服務架構介紹

微服務架構(Microservice Architecture)是一種架構概念,旨在通過將功能分解到各個離散的服務中以實現對解決方案的解耦。你可以將其看作是在架構層次而非獲取服務的類上應用很多 SOLID 原則。微服務架構是個很有趣的概念,它的主要作用是將功能分解到離散的各個服務當中,從而降低系統的耦合性,並提供更加靈活的服務支持。

概念: 把一個大型的單個應用程序和服務拆分爲數個甚至數十個的支持微服務,它可擴展單個組件而不是整個的應用程序堆棧,從而滿足服務等級協議。

定義: 圍繞業務領域組件來創建應用,這些應用可獨立地進行開發、管理和迭代。在分散的組件中使用雲架構和平臺式部署、管理和服務功能,使產品交付變得更加簡單。

本質: 用一些功能比較明確、業務比較精練的服務去解決更大、更實際的問題。

二、出現和發展

微服務(Microservice)這個概念是 2012 年出現的,作爲加快 Web 和移動應用程序開發進程的一種方法,2014 年開始受到各方的關注,而 2015 年,可以說是微服務的元年;

越來越多的論壇、社區、blog 以及互聯網行業巨頭開始對微服務進行討論、實踐,可以說這樣更近一步推動了微服務的發展和創新。而微服務的流行,Martin Fowler 功不可沒。

這老頭是個奇人,特別擅長抽象歸納和製造概念。特別是微服務這種新生的名詞,都有一個特點:一解釋就懂,一問就不知,一討論就打架。

Martin Fowler 是國際著名的 OO 專家,敏捷開發方法的創始人之一,現爲 ThoughtWorks 公司的首席科學家。在面向對象分析設計、UML、模式、軟件開發方法學、XP、重構等方面,都是世界頂級的專家,現爲 Thought Works 公司的首席科學家。Thought Works 是一家從事企業應用開發和——集成的公司。早在 20 世紀 80 年代,Fowler 就是使用對象技術構建多層企業應用的倡導者,他著有幾本經典書籍:《企業應用架構模式》、《UML 精粹》和《重構》等。                                                     ———— 百度百科

三、傳統開發模式和微服務的區別

先來看看傳統的 web 開發方式,通過對比比較容易理解什麼是 Microservice Architecture。和 Microservice 相對應的,這種方式一般被稱爲 Monolithic(單體式開發)。

所有的功能打包在一個 WAR 包裏,基本沒有外部依賴(除了容器),部署在一個 JEE 容器(Tomcat,JBoss,WebLogic)裏,包含了 DO/DAO,Service,UI 等所有邏輯。

優點:

①開發簡單,集中式管理

②基本不會重複開發

③功能都在本地,沒有分佈式的管理和調用消耗

缺點:

1、效率低:開發都在同一個項目改代碼,相互等待,衝突不斷

2、維護難:代碼功功能耦合在一起,新人不知道何從下手

3、不靈活:構建時間長,任何小修改都要重構整個項目,耗時

4、穩定性差:一個微小的問題,都可能導致整個應用掛掉

5、擴展性不夠:無法滿足高併發下的業務需求

常見的系統架構遵循的三個標準和業務驅動力:

1、提高敏捷性:及時響應業務需求,促進企業發展

2、提升用戶體驗:提升用戶體驗,減少用戶流失

3、降低成本:降低增加產品、客戶或業務方案的成本

基於微服務架構的設計:

目的: 有效的拆分應用,實現敏捷開發和部署

關於微服務的一個形象表達:

X 軸: 運行多個負載均衡器之後的運行實例

Y 軸: 將應用進一步分解爲微服務(分庫)

Z 軸: 大數據量時,將服務分區(分表)

四、微服務的具體特徵

官方的定義:

1、一些列的獨立的服務共同組成系統

2、單獨部署,跑在自己的進程中

3、每個服務爲獨立的業務開發

4、分佈式管理

5、非常強調隔離性

大概的標準:

1、分佈式服務組成的系統

2、按照業務,而不是技術來劃分組織

3、做有生命的產品而不是項目

4、強服務個體和弱通信( Smart endpoints and dumb pipes )

5、自動化運維( DevOps )

6、高度容錯性

7、快速演化和迭代

五、SOA 和微服務的區別

1、SOA 喜歡重用,微服務喜歡重寫

SOA 的主要目的是爲了企業各個系統更加容易地融合在一起。說到 SOA 不得不說 ESB(EnterpriseService Bus)。ESB 是什麼? 可以把 ESB 想象成一個連接所有企業級服務的腳手架。通過 service broker,它可以把不同數據格式或模型轉成 canonical 格式,把 XML 的輸入轉成 CSV 傳給 legacy 服務,把 SOAP 1.1 服務轉成 SOAP 1.2 等等。它還可以把一個服務路由到另一個服務上,也可以集中化管理業務邏輯,規則和驗證等等。它還有一個重要功能是消息隊列和事件驅動的消息傳遞,比如把 JMS 服務轉化成 SOAP 協議。各服務間可能有複雜的依賴關係。

微服務 通常由重寫一個模塊開始。要把整個巨石型的應用重寫是有很大的風險的,也不一定必要。我們向微服務遷移的時候通常從耦合度最低的模塊或對擴展性要求最高的模塊開始,把它們一個一個剝離出來用敏捷地重寫,可以嘗試最新的技術和語言和框架,然 後單獨佈署。它通常不依賴其他服務。微服務中常用的 API Gateway 的模式主要目的也不是重用代碼,而是減少客戶端和服務間的往來。API gateway 模式不等同與 Facade 模式,我們可以使用如 future 之類的調用,甚至返回不完整數據。

2、SOA 喜歡水平服務,微服務喜歡垂直服務

SOA 設計喜歡給服務分層 (如 Service Layers 模式)。我們常常見到一個 Entity 服務層的設計,美其名曰 Data Access Layer。這種設計要求所有的服務都通過這個 Entity 服務層來獲取數據。這種設計非常不靈活,比如每次數據層的改動都可能影響到所有業務層的服務。而每個微服務通常有它自己獨立的 data store。我們在拆分數據庫時可以適當的做些去範式化 (denormalization),讓它不需要依賴其他服務的數據。

微服務 通常是直接面對用戶的,每個微服務通常直接爲用戶提供某個功能。類似的功能可能針對手機有一個服務,針對機頂盒是另外一個服務。在 SOA 設計模式中這種情況通常會用到 Multi-ChannelEndpoint 的模式返回一個大而全的結果兼顧到所有的客戶端的需求。

3、SOA 喜歡自上而下,微服務喜歡自下而上

SOA 架構在設計開始時會先定義好服務合同 (service contract)。它喜歡集中管理所有的服務,包括集中管理業務邏輯,數據,流程,schema,等等。它使用 Enterprise Inventory 和 Service Composition 等方法來集中管理服務。SOA 架構通常會預先把每個模塊服務接口都定義好。模塊系統間的通訊必須遵守這些接口,各服務是針對他們的調用者。

SOA 架構適用於 TOGAF 之類的架構方法論。

微服務 則敏捷得多。只要用戶用得到,就先把這個服務挖出來。然後針對性的,快速確認業務需求,快速開發迭代。

六、怎麼具體實踐微服務

要實際的應用微服務,需要解決一下四點問題:

1、客戶端如何訪問這些服務

2、每個服務之間如何通信

3、如此多的服務,如何實現?

4、服務掛了,如何解決?(備份方案,應急處理機制)

**1、客戶端如何訪問這些服務

原來的 Monolithic 方式開發,所有的服務都是本地的,UI 可以直接調用,現在按功能拆分成獨立的服務,跑在獨立的一般都在獨立的虛擬機上的 Java 進程了。客戶端 UI 如何訪問他的?

後臺有 N 個服務,前臺就需要記住管理 N 個服務,一個服務下線 / 更新 / 升級,前臺就要重新部署,這明顯不服務我們 拆分的理念,特別當前臺是移動應用的時候,通常業務變化的節奏更快。

另外,N 個小服務的調用也是一個不小的網絡開銷。還有一般微服務在系統內部,通常是無 狀態的,用戶登錄信息和權限管理最好有一個統一的地方維護管理(OAuth)。

所以,一般在後臺 N 個服務和 UI 之間一般會一個代理或者叫 API Gateway,他的作用包括:

① 提供統一服務入口,讓微服務對前臺透明

② 聚合後臺的服務,節省流量,提升性能

③ 提供安全,過濾,流控等 API 管理功能

其實這個 API Gateway 可以有很多廣義的實現辦法,可以是一個軟硬一體的盒子,也可以是一個簡單的 MVC 框架,甚至是一個 Node.js 的服務端。他們最重要的作 用是爲前臺(通常是移動應用)提供後臺服務的聚合,提供一個統一的服務出口,解除他們之間的耦合,不過 API Gateway 也有可能成爲單點故障點或者性能的瓶頸。

用過 Taobao Open Platform(淘寶開放平臺)的就能很容易的體會,TAO 就是這個 API Gateway。

2、每個服務之間如何通信

所有的微服務都是獨立的 Java 進程跑在獨立的虛擬機上,所以服務間的通信就是 IPC(inter process communication),已經有很多成熟的方案。現在基本最通用的有兩種方式:

同步調用:

①REST(JAX-RS,Spring Boot)

②RPC(Thrift, Dubbo)

異步消息調用 (Kafka, Notify, MetaQ)

img

同步和異步的區別:

一般同步調用比較簡單,一致性強,但是容易出調用問題,性能體驗上也會差些,特別是調用層次多的時候。RESTful 和 RPC 的比較也是一個很有意 思的話題。

一般 REST 基於 HTTP,更容易實現,更容易被接受,服務端實現技術也更靈活些,各個語言都能支持,同時能跨客戶端,對客戶端沒有特殊的要求,只要封裝了 HTTP 的 SDK 就能調用,所以相對使用的廣一些。RPC 也有自己的優點,傳輸協議更高效,安全更可控,特別在一個公司內部,如果有統一個 的開發規範和統一的服務框架時,他的開發效率優勢更明顯些。就看各自的技術積累實際條件,自己的選擇了。

而異步消息的方式在分佈式系統中有特別廣泛的應用,他既能減低調用服務之間的耦合,又能成爲調用之間的緩衝,確保消息積壓不會沖垮被調用方,同時能保證調用方的服務體驗,繼續幹自己該乾的活,不至於被後臺性能拖慢。不過需要付出的代價是一致性的減弱,需要接受數據最終一致性;還有就是後臺服務一般要 實現冪等性,因爲消息發送出於性能的考慮一般會有重複(保證消息的被收到且僅收到一次對性能是很大的考驗);最後就是必須引入一個獨立的 broker,如果公司內部沒有技術積累,對 broker 分佈式管理也是一個很大的挑戰。

3、如此多的服務,如何實現?

在微服務架構中,一般每一個服務都是有多個拷貝,來做負載均衡。一個服務隨時可能下線,也可能應對臨時訪問壓力增加新的服務節點。服務之間如何相互感知?服務如何管理?

這就是服務發現的問題了。一般有兩類做法,也各有優缺點。基本都是通過 zookeeper 等類似技術做服務註冊信息的分佈式管理。當服務上線時,服務提供者將自己的服務信息註冊到 ZK(或類似框架),並通過心跳維持長鏈接,實時更新鏈接信息。服務調用者通過 ZK 尋址,根據可定製算法, 找到一個服務,還可以將服務信息緩存在本地以提高性能。當服務下線時,ZK 會發通知給服務客戶端。

客戶端做: 優點是架構簡單,擴展靈活,只對服務註冊器依賴。缺點是客戶端要維護所有調用服務的地址,有技術難度,一般大公司都有成熟的內部框架支持,比如 Dubbo。

服務端做: 優點是簡單,所有服務對於前臺調用方透明,一般在小公司在雲服務上部署的應用採用的比較多。

img

**4、服務掛了,如何解決

前面提到,Monolithic 方式開發一個很大的風險是,把所有雞蛋放在一個籃子裏,一榮俱榮,一損俱損。而分佈式最大的特性就是網絡是不可靠的。通過微服務拆分能降低這個風險,不過如果沒有特別的保障,結局肯定是噩夢。所以當我們的系統是由一系列的服務調用鏈組成的時候,我們必須確保任一環節出問題都不至於影響整體鏈路。相應的手段有很多:

①重試機制

②限流

③熔斷機制

④負載均衡

⑤降級(本地緩存)

這些方法基本都很明確通用,比如 Netflix 的 Hystrix:https://github.com/Netflix/Hystrix

img

七、常見的設計模式和應用

有一個圖非常好的總結微服務架構需要考慮的問題,包括:

1、API Gateway

2、服務間調用

3、服務發現

4、服務容錯

5、服務部署

6、數據調用

img

六種常見的微服務架構設計模式:

1、聚合器微服務設計模式

這是一種最常見也最簡單的設計模式:

img

聚合器調用多個服務實現應用程序所需的功能。它可以是一個簡單的 Web 頁面,將檢索到的數據進行處理展示。它也可以是一個更高層次的組合微服務,對檢索到的數據增加業務邏輯後進一步發佈成一個新的微服務,這符合 DRY 原則。另外,每個服務都有自己的緩存和數據庫。如果聚合器是一個組合服務,那麼它也有自己的緩存和數據庫。聚合器可以沿 X 軸和 Z 軸獨立擴展。

2、代理微服務設計模式

這是聚合模式的一個變種,如下圖所示:

img

在這種情況下,客戶端並不聚合數據,但會根據業務需求的差別調用不同的微服務。代理可以僅僅委派請求,也可以進行數據轉換工作。

3、鏈式微服務設計模式

這種模式在接收到請求後會產生一個經過合併的響應,如下圖所示:

img

在這種情況下,服務 A 接收到請求後會與服務 B 進行通信,類似地,服務 B 會同服務 C 進行通信。所有服務都使用同步消息傳遞。在整個鏈式調用完成之前,客戶端會一直阻塞。

因此,服務調用鏈不宜過長,以免客戶端長時間等待。

4、分支微服務設計模式

這種模式是聚合器模式的擴展,允許同時調用兩個微服務鏈,如下圖所示:

img

5、數據共享微服務設計模式

自治是微服務的設計原則之一,就是說微服務是全棧式服務。但在重構現有的 “單體應用(monolithic application)” 時,SQL 數據庫反規範化可能會導致數據重複和不一致。

因此,在單體應用到微服務架構的過渡階段,可以使用這種設計模式,如下圖所示:

img

在這種情況下,部分微服務可能會共享緩存和數據庫存儲。不過,這隻有在兩個服務之間存在強耦合關係時纔可以。對於基於微服務的新建應用程序而言,這是一種反模式。

6、異步消息傳遞微服務設計模式

雖然 REST 設計模式非常流行,但它是同步的,會造成阻塞。因此部分基於微服務的架構可能會選擇使用消息隊列代替 REST 請求 / 響應,如下圖所示:

img

八、優點和缺點

1、微服務的優點:

關鍵點: 複雜度可控,獨立按需擴展,技術選型靈活,容錯,可用性高

它解決了複雜性的問題。它會將一種怪異的整體應用程序分解成一組服務。雖然功能總量 不變,但應用程序已分解爲可管理的塊或服務。每個服務都以 RPC 或消息驅動的 API 的形式定義了一個明確的邊界;Microservice 架構模式實現了一個模塊化水平。

這種架構使每個服務都能夠由專注於該服務的團隊獨立開發。開發人員可以自由選擇任何有用的技術,只要該服務符合 API 合同。當然,大多數組織都希望避免完全無政府狀態並限制技術選擇。然而,這種自由意味着開發人員不再有義務使用在新項目開始時存在的可能過時的技術。在編寫新服務時,他們可以選擇使用當前的技術。此外,由於服務相對較小,因此使用當前技術重寫舊服務變得可行。

Microservice 架構模式使每個微服務都能獨立部署。開發人員不需要協調部署本地服務的變更。這些變化可以在測試後儘快部署。例如,UI 團隊可以執行 A | B 測試,並快速迭代 UI 更改。Microservice 架構模式使連續部署成爲可能。

Microservice 架構模式使每個服務都可以獨立調整。您可以僅部署滿足其容量和可用性限制的每個服務的實例數。此外,您可以使用最符合服務資源要求的硬件。

2、微服務的缺點

關鍵點(挑戰): ,系統部署依賴,服務間通信成本,數據一致性,系統集成測試,重複工作,性能監控等

一個缺點是名稱本身。術語 microservice 過度強調服務規模。但重要的是要記住,這是一種手段,而不是主要目標。微服務的目標是充分分解應用程序,以便於敏捷應用程序開發和部署。

微服務器的另一個主要缺點是分佈式系統而產生的複雜性。開發人員需要選擇和實現基於消息傳遞或 RPC 的進程間通信機制。此外,他們還必須編寫代碼來處理部分故障,因爲請求的目的地可能很慢或不可用。

微服務器的另一個挑戰是分區數據庫架構。更新多個業務實體的業務交易是相當普遍的。但是,在基於微服務器的應用程序中,您需要更新不同服務所擁有的多個數據庫。使用分佈式事務通常不是一個選擇,而不僅僅是因爲 CAP 定理。許多今天高度可擴展的 NoSQL 數據庫都不支持它們。你最終不得不使用最終的一致性方法,這對開發人員來說更具挑戰性。

測試微服務應用程序也更復雜。服務類似的測試類將需要啓動該服務及其所依賴的任何服務(或至少爲這些服務配置存根)。再次,重要的是不要低估這樣做的複雜性。

Microservice 架構模式的另一個主要挑戰是實現跨越多個服務的更改。例如,我們假設您正在實施一個需要更改服務 A,B 和 C 的故事,其中 A 取決於 B 和 B 取決於 C. 在單片應用程序中,您可以簡單地更改相應的模塊,整合更改,並一次性部署。相比之下,在 Microservice 架構模式中,您需要仔細規劃和協調對每個服務的更改。例如,您需要更新服務 C,然後更新服務 B,然後再維修 A. 幸運的是,大多數更改通常僅影響一個服務,而需要協調的多服務變更相對較少。

部署基於微服務的應用程序也更復雜。單一應用程序簡單地部署在傳統負載平衡器後面的一組相同的服務器上。每個應用程序實例都配置有基礎架構服務(如數據庫和消息代理)的位置(主機和端口)。相比之下,微服務應用通常由大量服務組成。例如,每個服務將有多個運行時實例。更多的移動部件需要進行配置,部署,擴展和監控。此外,您還需要實現服務發現機制,使服務能夠發現需要與之通信的任何其他服務的位置(主機和端口)。傳統的基於故障單和手動操作的方法無法擴展到這種複雜程度。因此,成功部署微服務應用程序需要開發人員更好地控制部署方法,並實現高水平的自動化。

九、思考:意識的轉變

微服務對我們的思考,更多的是思維上的轉變。對於微服務架構:技術上不是問題,意識比工具重要。

關於微服務的幾點設計出發點:

1、應用程序的核心是業務邏輯,按照業務或客戶需求組織資源(這是最難的)

2、做有生命的產品,而不是項目

3、頭狼戰隊,全棧化

4、後臺服務貫徹 Single Responsibility Principle(單一職責原則)

5、VM->Docker (to PE)

6、DevOps (to PE)

同時,對於開發同學,有這麼多的中間件和強大的 PE 支持固然是好事,我們也需要深入去了解這些中間件背後的原理,知其然知其所以然,在有限的技術資源如何通過開源技術實施微服務?

最後,一般提到微服務都離不開 DevOps 和 Docker,理解 微服務架構是核心,devops 和 docker 是工具,是手段。

十、參考資料和推薦閱讀:

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/Xv-ydWdoHhPHyb-X0YHg1A