微服務設計學習(一)關於微服務和如何建模服務

Richard_Yi發表於2019-10-07

undefined

前言

隨著網際網路在21世紀初被大規模接入,網際網路由基於流量點選贏利的單方面資訊釋出的Web 1.0業務模式,轉變為由使用者主導而生成內容的Web 2.0業務模式。因此,網際網路應用系統所需處理的訪問量和資料量均疾速增長,後端技術架構也因此面臨著巨大的挑戰。

Web 2.0階段的網際網路後端架構大多經歷了由All in One的單體式應用架構漸漸轉為更加靈活的分散式應用架構的過程,網際網路開發架構開始追求更高的質量和效率。

隨著智慧手機的出現以及4G標準的普及,網際網路應用由PC端迅速轉向更加自由的移動端。移動裝置由於攜帶方便且便於定位,因此在出行、網路購物、支付等方面徹底改變了現代人的生活方式。在技術方面,為了應對更加龐大的叢集規模,單純的分散式系統已經難於駕馭,因此技術圈開啟了一個概念爆發的時代——SOA、DevOps、容器、CI/CD、微服務、Service Mesh等概念層出不窮,而Docker、Kubernetes、Mesos、Spring Cloud、gRPC、Istio等一系列產品的出現,標誌著雲時代已真正到來

本文(或者說本系列文章),是本人在閱讀完 Sam Newman 的《微服務設計》一書之後,與其他的微服務設計相關文章、《從服務化到雲原生》等書籍進行關聯閱讀後做的筆記總結。

目的是構建分散式、微服務、雲原生方面的體系化的知識結構樹。

希望鞏固學習的同時能夠幫助到你。

一、關於微服務

1.1 什麼是微服務

微服務就是一些協同工作的小而自治的服務。

關鍵詞: 小而自治

“小”

“小”這個概念,一方面體現在微服務的內聚性上。

  • 內聚性也可以稱之為單一職責原則:“把因相同原因而變化的東西聚合到一起,而把因不同原因而變化的東西分離開來。
  • 也就是說,微服務應該專注於做好一件事情。
  • 由業務邊界來確定服務的邊界

另一方面體現在程式碼庫的大小,這裡有幾個參考的標準或者說原則

  • 程式碼庫小到團隊結構相匹配
  • 程式碼庫小到易於迅速重寫
  • 辯證的看待。服務越小,微服務架構的優點和缺點也就越明顯

自治

“自治”這個概念,強調的是,一個微服務就是一個獨立的實體。體現在服務之間的鬆耦合上。

  • 黃金法則:你是否能夠修改一個服務並對其進行部署,而不影響其他任何服務?

關鍵點:要學會正確的建模服務,正確的設計服務API,才能做到上述兩點。

1.2 微服務的好處

微服務的大多好處都適用於分散式系統架構,只不過微服務會將這些好處推向極致

  • 技術異構性
    • 不同服務根據業務場景、效能要求、功能需求採用不同的技術架構
    • 新技術的快速實踐,技術團隊的快速成長
  • 彈性/反脆弱性(anti-fragility)
    • 服務降級
    • 服務容災、服務熔斷
  • 擴充套件
    • 傳統單體系統,無法做到對區域性功能進行擴充套件
    • 根據具體的業務需求,對特定的微服務進行擴充套件
    • 通過架構的手段,節省成本
  • 簡化部署
    • 傳統單體應用,即使是一行程式碼修改,也需要整體重新部署。風險太大。
    • 微服務架構,各個服務部署相互獨立
      • 靈活的發版方式
      • 快速回滾
      • 風險小
  • 架構與組織結構相匹配
    • 關聯知識點:康威定律
  • 服務的可重用、可組合
  • 服務的可替代性,快速重寫

1.3 面向服務的架構

SOA(Service-Oriented Architecture,面向服務的架構)是一種設計方法,其中包含多個服務,而服務之間通過配合最終會提供一系列功能。一個服務通常以獨立的形式存在於作業系統程式中。服務之間通過網路呼叫,而非採用程式內呼叫的方式進行通訊。

就像認為 XP 或者 Scrum 是敏捷軟體開發的一種特定方法一樣,微服務架構是 SOA 的一種特定方法

實施SOA會遇到的問題:

  • 通訊協議(SOAP or REST)
  • 第三方中介軟體選型
  • 服務粒度劃分
  • ......

思考與小結

微服務確實有許多優點:“反脆弱性(anti-fragility)”、容錯、獨立部署與擴充套件、架構抽象、技術隔離。但並不是說採用了微服務就自然地具備了這些特性。

比如,要具備反脆弱性,需要充分考慮分散式系統的不確定性,清楚非同步、網路劃分、節點故障、平衡可用性與資料一致性等問題

同樣地,要具備可維護性和可擴充套件性,首先要有恰當的基礎設施和組織結構

理論上講,微服務可以提高開發速度,但在建立組織依賴時,“微服務佣金(MicroservicePremium)”可能會降低開發速度。

所以,採用微服務架構需要具備一些先決條件,包括恰當的持續釋出管道、能勝任的DevOps 和Ops 團隊、審慎的服務邊界等等。此外,周密的測試和整合模式也很重要。

就書中這章最後一講說的:微服務不是銀彈,你需要在部署、測試和監控等方面做很多的工作。你還需要考慮如何擴充套件系統、並且保證他們的彈性,甚至還需要處理類似分散式事務、CAP相關的問題。

我覺得,這也是為什麼服務化到雲原生是大勢所趨,因為只有結合“容器 +編排排程”的雲平臺,微服務才能將自己的優點發揮到最大。至於雲原生的知識,又是後面的內容了。

引申閱讀 Martin Fowler大神的文章

微服務佣金 www.martinfowler.com/bliki/Micro…

二、如何建模服務

還是要重申兩個重要概念,高內聚和鬆耦合,對應前面的關鍵詞:小而自治

2.1 幾個概念

限界上下文

此處作者引用了 Eric Evans 的著作《領域驅動設計》中的概念(這本書強烈建議閱讀):限界上下文

任何一個給定的領域都包含多個限界上下文,每個限界上下文中的東西(Eric 更常使用模型這個詞,應該比“東西”好得多)分成兩部分,一部分不需要與外部通訊,另一部分則需要。每個上下文都有明確的介面,該介面決定了它會暴露哪些模型給其他的上下文。 使用細胞作為比喻:“細胞之所以會存在,是因為細胞膜定義了什麼在細胞內,什麼在細胞外,並且確定了什麼物質可以通過細胞膜。”

共享模型和隱藏模型

同時又提到共享模型和隱藏模型的概念。

共享模型就是上述比喻中上下文之間互動的模型,隱藏模型就是不需要與外部進行互動的模型。

image.png


關於如何開始微服務,作者在書中的觀點和同在TW的Martin Fowler是一個觀點:"MonolithFirst" - 單體應用先行。

undefined

主要出於以下考慮:

  • Yagni 原則——確定軟體思路是否有用,最好的方法是建立一個簡化版本,然後看它的使用效果。在這個階段,最重要的是速度,而該原則可縮短反饋週期,避免微服務佣金。
  • 明確的有界上下文集合——只有服務存在良好且穩定的邊界,微服務才能有效地發揮作用。但是,任何微服務間的功能重構都比在單體架構中難度大,即使是經驗豐富的架構師在自己熟悉的領域裡,也很難在一開始就恰當地定義出邊界,而首先構建一個單體應用有利於明確功能邊界。

引申閱讀 www.martinfowler.com/bliki/Monol…

當然這和他們所處的公司業務環境肯定有很大的關係,ThoughtWorks 是一家幫助其他公司解決問題的顧問公司,也就是說,他們會在某個公司的單體應用出現問題時提供幫助,將其重構為微服務架構。得出這樣的結論也無可厚非。業界關於這個也有其他的聲音,比如直接就從微服務開始。

我本人是比較傾向於這種方式,所以對這種方式進行了摘錄和學習。

2.2 建模要點

  • 切忌過早劃分

    過早將一個系統劃分成為微服務的代價非常高,尤其是在面對新領域時。很多時候,將一個已有的程式碼庫劃分成微服務,要比從頭開始構建微服務簡單得多。

  • 確定限界上下文

    使用模組對限界上下文進行建模,同時使用共享和隱藏模型。

  • 從業務功能入手

    思考限界上下文的時候,應該從業務功能入手,首先要問自己“這個上下文是做什麼用的”,然後再考慮“它需要什麼樣的資料”。

  • 逐步劃分上下文

    當考慮微服務的邊界時,首先考慮比較大的、粗粒度的那些上下文,然後當發現合適的縫隙後,再進一步劃分出那些巢狀的上下文。

    • 巢狀上下文

image.png

  • 頂層上下文

image.png

思考與總結

如何在問題空間中尋找能達到高內聚低耦合的接縫。限界上下文是尋找這些接縫的一個非常重要的工具,通過將微服務與這些邊界相匹配,可以保證最終的系統能夠得到微服務提供的所有好處。

這一部分可以關聯學習DDD理念相關書籍。

相關文章