微服務架構實踐原則
好的微服務架構可以幫助團隊加快產品發佈,爲用戶提供更好的服務體驗。但什麼纔是好的微服務架構?這篇文章簡單介紹了微服務架構的設計原則。原文:Medium Microservice Architecture Practice[1]
許多初創公司的技術棧會從單體 Node.js 應用開始,然後構建幾個衛星通信服務,但並沒有系統採用微服務架構。隨着系統變得越來越複雜,團隊必須構建一個更好的解決方案來最小化對系統的影響。微服務體系架構的目標就是幫助工程師團隊更快、更安全、更高質量的交付產品。
在微服務體系架構中,多個鬆散耦合的服務一起工作,每個服務專注於一個目標,並與相關行爲和數據保持高度內聚。其定義包括 3 條設計原則:
-
單一職責——每項服務都應該專注於一個目的並把它做好
-
松耦合服務——服務之間沒有太多的聯繫,對一個服務的變更不應該要求更改其他服務,服務之間的通信只能通過公開的服務接口進行。
-
高內聚性——每個服務都將所有相關的行爲和數據封裝在一起,如果需要構建新功能,所有的更改都應該侷限於一個服務中。
這些原則是充分利用微服務體系架構潛力的唯一途徑,任意兩者的缺乏都將使之成爲一種反模式。如果沒有一個單一的職責,每個微服務最終都會做很多事情,併成長爲多個 “單體” 服務,因此我們沒法從微服務架構中獲得好處,但卻需要支付運營成本。如果沒有松耦合,對一個服務的更改會影響到其他服務,因此我們沒法快速安全的發佈變更,而這正是微服務體系架構的核心優勢。更重要的是,由緊耦合引起的問題可能是災難性的,比如數據不一致甚至數據丟失。如果沒有高內聚性,我們將最終得到一個分佈式的單體系統,一組混亂的服務,必須在構建單一功能的同時進行更改和部署。由於多服務協調(有時跨多個團隊)的複雜性和成本,分佈式單體系統通常比集中式單體系統還要差勁。
此外,微服務不是代碼行更少或處理小任務的服務,只要滿足了這 3 個原則,服務就可以實現複雜而重要的功能。事實上,由於我們可以直接從單體服務中提取邏輯,因此微服務並不總是採用新技術或者從頭開始構建的。
Node.js 單體應用在很多方面已經成爲瓶頸。首先,最大的瓶頸是性能。某些計算量大、I/O 量大的任務不適合 Node.js。我們一直在逐步改進這個整體應用程序,但事實證明這種努力收效甚微。其次,另一個緊迫的瓶頸是單體應用程序減緩了產品開發。所有工程師都在一個應用程序中構建功能,所以這些服務通常是緊密耦合的,因爲對系統某一部分的更改也會影響到其他部分,因此很難對系統進行靈活的變更。因爲影響難以預測,我們也害怕做出重大變更。整個應用程序作爲一個整體部署,如果部署由於不正確的提交而停滯,則無法完成其他所有變更。在這種情況下,微服務體系架構適合於交付更好的複雜系統。在我們新的微服務體系架構中,更改可以一小時內發佈到生產環境,工程師不必擔心會影響系統的其他部分。第三,單體應用程序很難爲特定任務擴展系統。單體應用程序只能擴展整個系統,這將導致其他簡單任務的過度配置。我們分割了不同類型的請求來分離 Node.js 進程,但因爲這些單體服務的迷你版本仍然是緊耦合的,因此伸縮性仍然受限。最後,最緊迫的瓶頸是它阻止我們嘗試新技術。微服務體系架構的主要優點之一是,每個服務都可以使用不同的技術棧構建,並與不同的技術集成。這樣,我們就可以爲特定的工作找到合適的工具,並安全快速地完成任務。
在採用微服務體系架構時,我們會面臨什麼問題?
微服務也有可能出問題,並在實際上損害生產環境。有 7 種策略可以幫助我們:
-
用清晰的思路構建新的服務
-
單一的持久化存儲是有害的
-
解耦 “構建服務” 和“運行服務”
-
詳細一致的可觀測性
-
注意失敗
-
從一開始就避免 “微服務綜合症”
用清晰的思路構建新的服務
- 有人可能認爲,採用新的服務端架構意味着需要長期暫停產品開發並且重寫所有內容。但實際上這是一種誤解,我們永遠不應該爲了構建新的服務而構建。每當我們建立一項新服務或採用一項新技術時,我們必須有一個清晰的產品理念或工程價值。產品價值是造福用戶,與單體 Node.js 應用相比,新服務需要提供更多的價值或更好的性能。工程價值指的是使工程團隊更好、更快的合作。如果構建一個既沒有產品價值也沒有工程價值的新服務,我們還不如仍然停留在單體應用中。
單一的持久化存儲是有害的
-
爲微服務建模只是微服務架構的一部分工作,另一大部分工作是爲持久化存儲的數據建模。跨服務共享持久數據存儲似乎是集成微服務的最簡單方法,然而,它實際上是有害的,我們應該不惜一切代價避免。首先,持久化數據存儲與實現細節有關,跨服務共享數據存儲將向整個系統公開服務的實現細節。如果服務更改了數據格式,或添加了緩存層,或切換到不同類型的數據庫,那麼其他服務也必須相應的更改,而這違反了松耦合原則。
-
另外,如何修改、描述和使用數據並不是一種服務行爲。如果我們跨服務共享數據存儲,意味着其他服務也必須複製這些服務行爲,而這違反了高內聚原則,會將給定域中的行爲泄露給多個服務。如果我們修改一個行爲,將不得不同時修改所有這些服務。
-
在微服務體系架構中,只有一個服務應該負責特定類型的數據,所有其他服務都應該通過服務 API 請求數據,或者保留只讀的非規範(可能是具化的)數據副本。
-
這聽起來可能有點抽象,這裏有一個具體的例子。假設我們正在構建一個新的推薦服務,需要來自發布數據表中的一些數據,該數據表目前存儲在 AWS Dynamo DB 中。我們可以通過以下兩種方式爲新的推薦服務提供發佈數據:
參考文獻
Microservices Best Pratices: https://medium.com/@kmdkhadeer/microservices-best-practices-5fe3e28394b3
References:
[1] Medium Microservice Architecture Practice: https://jinlow.medium.com/medium-microservice-architecture-practice-5a2d61fff9fa
你好,我是俞凡,在 Motorola 做過研發,現在在 Mavenir 做技術工作,對通信、網絡、後端架構、雲原生、DevOps、CICD、區塊鏈、AI 等技術始終保持着濃厚的興趣,平時喜歡閱讀、思考,相信持續學習、終身成長,歡迎一起交流學習。
微信公衆號:DeepNoMind
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/sVurpJ1VSpuEToiNFfTjaA