微服務設計原則

良好的微服務設計可使後期的升級維護更加輕鬆,不然將會使人很是頭疼。數據庫

下面幾個設計原則強烈建議採用:服務器

  • 單一職責
  • 高內聚
  • 低耦合網絡

    • 隱藏內部實現
    • 避免代碼庫共享
    • 避免數據過分暴露
    • 避免數據庫共享
    • 最小化同步調用
    • 最小化硬件共享
    • 避免使用平臺獨特性技術

這三大原則是面向對象設計中的核心,一樣適用於微服務設計。架構

1. 單一職責

每一個微服務只應擔負一個職責。

好比一個微服務中有兩大功能:異步

  • 商品分類管理
  • 購物車

把它們放在一塊兒看起來問題不大,由於使用的技術相同、功能和數據上會有比較緊密的聯繫,在組織結構上,一般是由同一個開發小組負責。微服務

可是,這會形成兩個功能有大量的代碼耦合。測試

時間長了以後,會帶來和單體架構同樣的問題,維護難、測試難、部署難 ……spa

因此,按照「單一職責」原則,應該分爲兩個微服務。設計

2. 高內聚

關係緊密的行爲應放在一塊兒。

好比有2個微服務:對象

  • 訂單管理
  • 訂單金額統計

「訂單金額統計」 服務須要請求 「訂單管理」 服務,以獲取所需數據。

例如價格、稅、服務費 ……

剛開始一切安好,但忽然某一天上頭增長稅種了,須要更改新的計算規則。

那麼,訂單服務就要提供新的數據,金額統計服務也須要更改計算方式。

也就是說,每次變動基本都須要兩個服務一塊兒改,是緊耦合的。

由於訂單金額統計服務的邏輯只與訂單相關,因此應該併入訂單服務。

把緊密相關的行爲放在一塊兒,實現高內聚。

3. 低耦合

一個服務的變動不要影響其餘服務。

此原則涉及到多個方面。

3.1 隱藏內部實現

好比上一節 「高內聚」 中,把金額統計服務併入了訂單管理服務,那麼,以前金額統計服務中的 「統計接口」 還須要對外暴露嗎?

如今已是訂單服務的內部功能了,統計結果能夠做爲訂單對象中的數據,因此無需對外暴露,防止誤操做和形成沒必要要的耦合關係。

3.2 避免共享代碼庫

共享代碼的確很是方便,可是會形成底層代碼關聯度太強。

對於之後的升級很是不便,例如某個服務想把語言版本升級,但共享庫使用的是低版本,其中某些用法在高版本中是過時的,這就很尷尬了。

想要完美的避免也是不現實的,只能儘可能規避。

例如不共享,各服務從新造輪子,這樣服務之間就有邊界了。

但這個方式只適用於須要共享的庫是很是穩定的,不怎麼須要改了,不然的話相關服務都須要改。

再好比把共享庫的粒度縮小,避免造成功能特別全的大庫。

大庫必然致使被引用的範圍很是廣,影響面大。

若是粒度很小的話,涉及的服務也就少。

3.3 避免數據過分暴露

例如用戶服務有一個獲取用戶詳情的接口,返回用戶全部信息。

購物車服務獲取用戶信息時,就會拿到很全的數據,例如包括支付信息。

這是不必的,只須要返回用戶的基本屬性便可。

特殊的屬性應經過另外的接口提供。

過分暴露會增長服務間的耦合度。

3.4 避免數據庫共享

一個服務想獲取另外一個服務的數據時,只應該經過接口,而不是直接從對方的數據庫中拿。

不然,這種數據層面的耦合會帶來噩夢。

3.5 最小化同步調用

好比訂單服務建立訂單的時候須要調用不少其餘服務,例如用戶、商品、支付、庫存、物流。

直接同步調用各個服務的接口嗎?

不現實,若是其中有一個服務接口調用失敗,那麼建立訂單就失敗了。

最好使用事件驅動的異步調用。

同步調用會產生網絡的阻塞,對被調用服務的可用性要求極高,因此要慎重使用。

3.6 避免硬件基礎設施的共享

服務設計得很好,但若是硬件部署沒有規劃好,同樣很是痛苦。

例如兩個服務部署在一臺服務器上,服務B 很是消耗資源,那麼服務A可能就無法用了。

因此,不能忽略硬件這個關鍵點,要根據各個服務的特色作好均衡部署。

3.7 避免使用平臺特性技術

例如 Java RMI 作遠程調用不錯,但它是平臺特性,要求服務雙方都用一套技術,這種高耦合就不如平臺獨立的 REST 更自由了。

相關文章
相關標籤/搜索