面試被問微服務答不上?分享微服務設計指南,你有什麼可豪橫的!

每個人都聽說過微服務。但你知道怎麼設計嗎?

微服務是當今軟件工程師的一個熱門話題。讓我們瞭解如何使用微服務架構風格構建真正模塊化、業務敏捷的IT系統。

正式定義

“微服務架構風格是一種將單個應用程序開發爲一組小型服務的方法,每個小服務運行在自己的進程中,並且以輕量級機制(通常是HTTP REST API)通信。這些服務是圍繞業務能力建立的,並且可以由完全自動化的部署機構獨立部署。這些服務的集中管理只有最低限度,可以用不同的編程語言編寫並使用不同的數據存儲技術。” —— James Lewis and Martin Fowler

定義微服務的特性

  • 每個服務都是一個輕量級、獨立和鬆散耦合的業務單元。
  • 每個服務都有自己的代碼庫,由一個小團隊管理和開發(主要是用於敏捷環境中)。
  • 每個服務負責一部分功能或者說業務能力,並且做得很好。
  • 每個服務都可以爲其用例選擇最佳的技術棧(無需將整個應用程序綁定在一個框架中)。
  • 每個服務都有自己的DevOps計劃(測試、發佈、部署、擴展、集成和獨立維護)。
  • 每個服務都部署在一個獨立自給的環境中。
  • 服務通過使用定義良好的API(智能端點)和簡單協議如基於HTTP 的REST協議(啞管道)相互通信。
  • 每個服務負責持久化自己的數據和保持外部狀態(只有當多個服務使用相同的數據時,這種情況纔在公共數據層中處理)。

白小白:

智能端點和啞管道,其實我一直認爲“啞”管道不如“笨”管道或者“呆”管道更易理解。防呆設計是一種預防用戶錯誤使用產品造成不良後果的設計理念,比如USB設計成一半有實體芯片,就是讓用戶可以不假思索的在插錯後直接掉轉方向再插。不讓用戶思考就是“呆”的含義。“啞”管道的“啞”其實就是體現在微服務的通信過程儘量簡單,不要讓通信機制有“思考能力”,不在其中加入過多的處理機制,反例是SOA時代的ESB產品,ESB產品通常會包含複雜的設施用於消息路由,編排和轉換,以及業務規則應用。反過來,智能端點的概念就容易理解了,也就是將與某服務相關的處理都限定在微服務的範疇之內,通信過程中的微服務端點是“智能”的,這也從一個方面體現了微服務“高內聚”的含義,有了高內聚,才能具備自治和獨立性,從而可以支持“鬆耦合”的機制。

微服務的好處

微服務可以用於擴展大型系統,也爲持續集成和交付提供了巨大的能力。

獨立縮放:《 The Art of Scalability》這本優秀的書中所描述的Scale Cube概念,是微服務架構所支持的。在開發微服務以實現功能分解時,應用程序通過Y軸自動縮放。當服務調用量較高時,微服務可以通過克隆更多的CPU和內存,通過X軸進行擴展。爲了在多臺機器上分發數據,可以分離大型數據庫(分庫分表)轉換成更小、更快、更容易管理的部件,從而實現Z軸的縮放。

獨立發佈和部署:使用微服務,Bug修復和特性發布更易於管理,風險更小。可以在不重新部署整個應用程序的情況下更新服務,並在出現問題時回滾或前滾更新。

獨立開發:每個服務都有自己的代碼庫,由一個小的焦點小組開發、測試和部署。開發人員可以專注於一種服務,並且只關注相對較小的範圍。這將提高生產率、項目速度、持續創新能力和源碼質量。

優雅降級:如果服務崩潰,其影響不會傳播到應用程序的其他部分,並導致系統發生災難性故障,從而體現某種程度的健壯性。

分散治理:開發人員可以自由選擇技術棧,制定最適合其服務的設計標準和實現決策。團隊不必因爲過去的技術決定而受到懲罰。

業務關切

獨立的服務本身並不能形成一個系統。要使微服務體系結構真正成功,需要大量投資來處理跨系統的問題,例如:

服務複製:一種讓服務易於擴展的基於元數據的機制
服務註冊和發現:啓用服務查找並查找服務端點的機制
服務監測和日誌:收集來自不同微服務的日誌的機制,並提供一致的報告
彈性:服務在故障期間自動採取糾正行動的機制
DevOps:處理持續集成和部署的機制(CI和CD)
API網關:爲客戶端提供入口的機制

中間件與設計模式

API網關(所有客戶端的單一入口點)

API網關風格的微服務體系結構,是用於微服務的最常見的設計模式。API網關是一箇中間層,具有最小化的路由功能,只是充當一個“啞管道”,裏面沒有業務邏輯。一般來說,API網關允許客戶端基於REST/HTTP調用託管的API。其他類型的微服務集成模式有:點對點風格(直接從客戶端應用程序調用服務)和消息代理風格(實現異步消息傳遞)。

API網關充當所有客戶端的單一入口點,API網關也作爲一種邊緣服務來將微服務作爲託管API公開給外部世界。這聽起來像是一個反向代理,但也有一些額外的責任,例如簡單的負載平衡,認證和授權,故障處理,審覈,協議轉換,和路由機制。開發團隊可以選擇以下方法之一來實現API網關。

自己編程實現:具有更好的客戶化和管控能力。

部署現有的API網關產品:節省初始開發時間,並使用高級內置功能(缺點在於:此類產品依賴於供應商,並不完全免費。配置和維護通常是冗長而耗時的)

解釋API網關行爲的一些設計模式如下(請參閱微服務設計模式 http://t.cn/RKx8bhG).

網關聚合(http://t.cn/EAvT2jl):將針對多個內部微服務的多個客戶端請求(通常是HTTP請求)聚合到單個客戶端請求中,減少了使用者和服務之間的交互和網絡延遲。

網關分流(http://t.cn/EAvTGmA):使單個微服務能夠將一些共享的服務功能分流到API網關級別。這些跨服務功能包括認證、授權、服務發現、容錯機制、QoS、負載平衡、日誌記錄、分析等。

網關路由(第7層路由,通常是HTTP請求 http://t.cn/EAvTMm4):使用單一入口端點將請求路由到內部微服務的端點,這樣服務調用者就不需要自行管理多個獨立的端點

請注意,API網關應該始終是一個高可用性和高性能的組件,因爲它是整個系統的入口點。

事件總線(用於異步事件驅動通信的、發佈/訂閱、中介通道)

應用程序的不同部分在進行相互通信時,無論消息的順序(爲處理異步的消息)或使用的語言(爲了體現語言無關性),都可以使用事件總線來實現。大多數事件總線支持發佈/訂閱、分佈式、點對點和請求響應消息傳遞。一些事件總線(如Vert.x)允許客戶端使用相同的事件總線與相應的服務器節點進行通信,這是全堆棧團隊所喜愛的一個很酷的特性。

服務網格(用於服務間通信的外掛(Sidecar)機制)

服務網格通過提供服務間通信的輔助架構來實現外掛模式,包括彈性(容錯、負載平衡)、服務發現、路由、可觀察性、安全性、訪問控制、通信協議支持等功能。

實際上,外掛實例部署在每個服務的旁邊(理想情況下是在同一個容器中)。他們可以通過服務本身的網絡功能來進行通信。服務網格的控制平面被單獨部署,以提供中心功能,如服務發現、訪問控制和可觀察性(監視、分佈式日誌記錄)。最重要的是,服務網格風格的設計模式允許開發人員從微服務代碼中分離網絡通信功能並使服務只關注於業務功能。(來自:Netflix Prana, 微服務網格)

儘管上面的圖片顯示了服務之間的直接連接,但是處理服務間通信的好方法是使用一個簡單的事件總線作爲中介,以保持最低級別的耦合。

聚合器(BFF模式)

如果應用程序需要裁剪每個API以適應客戶端應用程序類型(Web端、移動端以及其他不同平臺),則可以通過聚合器(Aggregator)執行不同的業務規則,也可以執行不同的配置以根據客戶端功能適配不同的構建。這可以在API網關級別實現,也可以在服務級別並行實現。這種模式對於提供特定的用戶體驗非常有用。但是,開發團隊應該足夠小心,將BFF保持在可管理的範圍內。

白小白:

“通過聚合器”,原文是“via a facade”,直譯是“通過一個外觀/門面”。門面模式(外觀模式),是一種Java的設計模式,爲子系統中的一組接口提供了一個統一的訪問接口,引申自一個前店後廠的生意模式,前面是門面,後面會有進料、生產、包裝多個服務。用在這裏是指將相關的服務通過聚合器聚合在一起,這個聚合器就是門面。服務調用者與門面交互而不是與一組服務交互降低了耦合性,但同時違反了面向對象設計原則開閉原則,開閉原則要求模塊在擴展時可以不改動內部的代碼,但顯然當聚合器後端的某個服務發生變更時,需要在聚合器層面也發生變更,這也是文中說“開發團隊應該足夠小心”的原因,因爲違反了開閉原則,就會降低可複用性。

最佳實踐

領域驅動設計:圍繞業務領域進行服務建模。

爲了處理大型模型和團隊,可以應用領域驅動設計(DDD)。DDD通過將大型模型劃分爲不同的有界上下文來明確他們之間的相互關係和子領域。這些有界上下文可以在應用設計級別轉換爲單獨的微服務。

分散數據管理(避免共享數據庫):當多個服務使用一個共享數據架構時,會在數據層形成緊耦合。爲了避免這種情況,每個服務都應該有自己的數據存取邏輯獨立數據存儲。開發團隊可以根據服務和數據性質的不同自由選擇最適合的數據持久性方法。

智能端點和啞管道:每個服務都擁有一個定義良好的外部通信API,並儘量避免泄露實現細節。通信則始終使用簡單協議,如基於HTTP的REST協議。

異步通信:當跨服務使用異步通信時,其他服務不會阻塞數據流。

避免服務耦合:服務應保持鬆耦合高內聚。產生耦合的主要原因包括共享數據庫模型和嚴格的通信協議。

分散開發:避免在多個服務/項目之間共享代碼庫、數據架構或開發團隊成員。讓開發者從源頭上關注創新和質量。

將領域知識排除在網關之外:讓網關處理路由和跨服務問題(如身份驗證、SSL終端等)。

基於令牌的認證:不要在每個微服務級別實現安全組件,因爲這將需要組件與集中式/共享用戶存儲庫對話並檢索身份驗證信息;而是考慮實現API網關級別的身份驗證,使用廣泛使用的API安全標準,如OAuth2和OpenID Connect。一旦從認證提供者獲得令牌之後,就可以用於與其他微服務進行通信。

事件驅動性質:既然人可以成爲對事件作出反應的自主主體,系統也可以。

最終一致性:由於微服務的高內聚特性,很難在整個系統內實現很強的一致性。因此開發團隊必須處理最終一致性。

容錯:由於系統由多個服務和中間件組成,因此在某些地方可能很容易發生故障。對於這些薄弱環節,有一些實現模式,如斷路器,防水艙,重試,超時,快速失敗,故障轉移緩存,速率限制,負載釋放,可以將重大故障的風險降到最低。

產品工程化:把微服務工程化爲一種產品,而不是作爲一個項目,可以讓微服務更好的發揮作用。這意味着,不能僅僅考慮能用而且及時交付,而是要長期致力於卓越的工程化。

微服務實踐

何時使用微服務

微服務架構最適合的應用場景:

  • 具有高可伸縮性需求的應用
  • 對交付速度要求較高的項目
  • 具有豐富域或多個子域的業務用例
  • 小型、跨功能的開發團隊協作開發大型產品的敏捷環境

一些實現微服務的入門框架

Vert.x:輕量級,易於理解/實現/維護,多語言支持(支持多種語言),事件驅動,非阻塞,可以說,具備了以最少的硬件處理高併發需求時的最佳性能和可伸縮性,並且具備足夠的開放性(與傳統的限制性框架不同,Vert.x只提供有用的組件,開發人員可以自由地創新並仔細構建他們的應用程序)

Akka:令人滿意的性能,實現了Actor模型(一種併發模型),有利於響應式微服務和事件驅型微服務

Spring Boot/Spring Cloud:容易上手(採用熟悉範式),基於良好的舊Spring框架,有點重的框架,許多集成可用,大規模的社區支持

Drop Wizard:有利於RESTful Web服務的快速開發,它搭載了一些不錯的Java工具和庫,如Google Guava、Jetty Server、Logback、Hibernate Validator、Joda Time、Jersey和Jackson。

部署選項

容器:有利於執行DevOps目標(快速開發,縮短上市時間,無縫縮放)

雲計算架構:有利於構建可靠和可伸縮的基礎設施,爲地理位置分散的用戶服務。

無服務器架構:適合處理高度不穩定的流量。

維護自己的IT基礎設施:對那些擁有足夠能力和資源建設整個基礎設施的組織來說是件好事。

微服務的開發理念

自給系統:由獨立系統組裝軟件(按業務垂直切分系統)

微前端:將單體應用的Web UI劃分爲獨立的特性,這些特性可以作爲獨立的UI組件開發,並直接與微服務進行通信。

需要搜索和學習的關鍵詞

領域驅動設計(DDD)**| 有界上下文(BC)| 聚合持久性(PP)| 命令和查詢責任隔離(CQRS)| 命令查詢分離(CQS)| 事件溯源(ES)| **CAP定理 **|**最終一致性 **|**十二要素應用 **|**SOLID原則 |

參考架構

此體系結構是由使用Microsoft技術的Microsoft開發人員提出的。在這裏,API Gateway是針對不同的Web和移動用戶而定製的。對於數據層,數據存儲技術是根據業務功能仔細選擇的(關係數據庫用於結構化數據,Redis用於臨時數據緩存,MongoDB和Cosmos DB用於非結構化數據)。事件總線處理服務間通信。撇開技術不說,這是基於微服務的應用最常見的集成模式

一種非阻塞應用程序的微服務體系結構,該應用程序使用來自各種事件源(例如交通數據、天氣指數、股票市場線索、社交媒體帖子、傳感器輸出)的大量輸入數據流來向最終用戶顯示實時更新。這些輸入數據流最初由使用Kafka實現的事件日誌收集。它將數據保存在磁盤上,因此可以用於批處理調用(分析、報告、數據科學、備份、審計)或用於實時調用(運營分析、CEP、管理儀表板、警報應用程序)。上圖中,使用Spark按指定的時間間隔,將持續的輸入數據流劃分爲微批次,並輸入到WSO2 Siddhi CEP引擎中。後者標識事件並使用MongoDB存儲以非結構化形式存儲數據。微服務調取這些數據並顯示給最終用戶。仔細觀察這一設計, Vert.x事件總線能夠創建與前端UI組件的連接,該特性僅用於有效地更新UI中的相關部分。撇開技術不說,這是基於事件驅動的非阻塞微服務應用程序的一個很好的架構。

用於訂單管理應用程序的雲原生泛渠道微服務體系結構(圖片:ibm.com)這個設計的一個主要特點是,IBM架構師沒有使用API網關,而是爲每個客戶端通道(移動應用程序、Web應用程序、IOT設備、API使用者)提出了一個具有獨立後端的邊緣層。另一個特點是將微服務層劃分爲業務邏輯層和基礎層兩個子層。基礎層(即核心服務層)使用各種雲原生服務(雲數據存儲、集成和索引Watson會話的Elastic搜索引擎)處理持久化和集成任務。業務邏輯層集成了基礎層的數據,並提供了有意義的業務功能。這將是一個很好的架構,可以爲地理上分散的大量用戶羣提供服務,並通過各種平臺訪問應用程序。


共同進步,學習分享

歡迎大家關注我的公衆號【風平浪靜如碼】,海量Java相關文章,學習資料都會在裏面更新,整理的資料也會放在裏面。

覺得寫的還不錯的就點個贊,加個關注唄!點關注,不迷路,持續更新!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章