簡明扼要的概述微服務設計原則,深入開發微服務,就從今天開始

寫在前面

領域驅動設計DDD (Domain Driven Design)提出了從業務設計到代碼實現一致性的要求,不再對分析模型和實現模型進行區分。也就是說,從代碼的結構中我們可以直接理解業務的設計,命名得當的話,非程序人員也可以“讀”代碼。這與微服務設計中的約定優於配置不謀而合,如果你熟悉英文,那麼根據包名和類名就可以解讀出程序開發者所構建的業務的大概意圖。

簡明扼要的微服務設計原則,深入開發微服務,就從今天開始

 

領域模型包含一些明確定義的類型:

  • 實體是一個對象,它有固定的身份,具有明確定義的“連續性線索”或生命週期。通常列舉的示例是一個Person (一個實體)。大多數系統都需要唯一地跟蹤一個Person,無論姓名、地址或其他屬性是否更改。
  • 值對象沒有明確定義的身份,而僅由它們的屬性定義。它們通常不可變,所以兩個相等的值對象始終保持相等。地址可以是與Person 關聯的值對象。
  • 集合是一個相關對象集羣,這些對象被看作一個整體。它擁有一個特定實體作爲它的根,並定義了明確的封裝邊界。它不只是一個列表。
  • 服務用於表示不是實體或值對象的自然部分的操作或活動。

領域模型在實現時可大可小,在業務的早期,在系統比較小的情況下,它有可能是一個類。當系統做大了以後,它可能是一個庫。再做更大- -點的時候,它可能是一個服務,給不同的應用去調用。

要將領域元素轉換爲服務,可按照以下一般準則來完成此操作:

  • 使用值對象表示作爲參數和返回值,將集合和實體轉換爲獨立的微服務。
  • 將領域服務(未附加到集合或實體的服務)與獨立的微服務相匹配。
  • 每個微服務應處理一個完整的業務功能。

從今天開始,咱們就來一塊學習微服務的設計原則!!!

分層架構

簡明扼要的微服務設計原則,深入開發微服務,就從今天開始

 

同一公司使用統一應用分層,以減少開發維護學習成本。應用分層看起來很簡單,但每個程序員都有自己的一套方法,哪怕是初學者,所以想實施起來並非那麼容易。

最早接觸的分層架構應該是我們最熟悉的MVC (Model-View-Controller) 架構,其將應用分成了模型、視圖和控制層,可以說引導了絕大多數開發者。而現在的應用(包括框架)中非常多架構設計都使用此模式。之後又演化出了MVP ( Model-View-Presenter)和MVVM(Model-View-ViewModel)。這些可以說都是隨着技術的不斷髮展,爲了應對不同場景所演化出來的模型。而微服務的每個架構都可以再細分成領域模型,下面看一下經典的領域模型架構。

它包括了Domain、Service 和Repositories。核心實體( Entity)和值對象(Value Object)應該在Domain層,定義的領域服務(Domain Service) 在Service層,而針對實體和值對象的存儲和查詢邏輯都應該在Repositories 層。值得注意的是,不要把Entity 的屬性和行爲分離到Domain和Service兩層中去實現,即所謂的貧血模型,事實證明這樣的實現方式會造成很大的維護問題。基於這種設計,工程的結構可以構造爲:

- MicroService Sample/src/ 
domain 
gateways 
interface 
repositories 
services

當然 ,在微服務的架構中, 每個微服務不必嚴格遵照這樣的規定,切忌死搬硬套,最重要的是理解業務。在不同的業務場合,架構的設計可以適當地調整,畢竟適合的架構定要具有靈活性。

分層的原則如下。

  • 文件夾分層法

應用分層採用文件夾方式的優點是可大可小、簡單易用、統一規範,可以包括5個項目, 也可以包括 50 個項目,以滿足所有業務應用的多種不同場景

  • 調用規約

在開發過程中,需要遵循分層架構的約束,禁止跨層次的調用。

  • 下層爲上層服務

以用戶爲中心,以目標爲導向。上層(業務邏輯層)需要什麼,下層(數據訪問層)就提供什麼,而不是下層(數據訪問層)有什麼,就向上層(業務邏輯層)提供什麼。

  • 實體層規約

Entity是數據表對象,不是數據訪問層對象; DTO是網絡傳輸對象,不是表現層對象; BO是內存計算邏輯對象,不是業務邏輯層對象,不是隻能給業務邏輯層使用。如果僅限定在本層訪問,則導致單個應用內大量沒有價值的對象轉換。以用戶爲中心來設計實體類,可以減少無價值重複對象和無用轉換。

  • U型訪問

下行時表現層是Input, 業務邏輯層是Process, 數據訪問層是Output。上行時 數據訪問層是Input,業務邏輯層是Process,表現層是Output。

通信協議

簡明扼要的微服務設計原則,深入開發微服務,就從今天開始

 

接口調用如果是遠程調用,那麼就構成了簡單的分佈式。最簡單的遠程接口實現方式是Web Service或REST.當然一一個 合理的分佈式應用不僅僅是遠程接口調用這麼簡單,還需要有負載均衡、緩存等功能。實現分佈式最簡單的技術是REST接口,因爲REST接口可以使用現存的各種服務器,比如使用負載均衡服務器和緩存服務器來實現負載均衡和緩存功能。

關於通信協議,不同的公司有不同的選擇,但是建議同一公司內部使用統--的通信協議,比較典型的有GRPC和BRPC。

GRPC是一個高性能、開源和通用的RPC框架,面向移動和HTTP/2設計。目前提供C、Java和Go語言版本,分別是GRPC、GRPC-Java, GRPC-Go,其中C版本支持C、C++、Node.js、Python、Ruby、 Objective-C、 PHP和C#。

GRPC基於HTTP/2標準設計,帶來諸如雙向流、流控、頭部壓縮、單TCP連接上的多複用請求等特性。這些特性使得其在移動設備上表現更好,更省電和節省空間佔用。

與GRPC類似,BRPC 源自百度,目前支撐百度內部大約75萬個同時在線的實例。

其實基於以上的幾種選擇都能夠完成高效的開發,團隊內部使用統一-的標準,這樣更有利於模塊化和統一標準。

服務間的通信通過輕量級的Web服務,使用同步的REST API進行通信。在實際的項目應用中,一般推薦在查詢時使用同步機制,在增刪改時使用異步的方式,結合消息隊列來實現數據的操作,以保證最終的數據一致性。

REST API應爲創建、檢索、更新和刪除操作使用標準HTTP動詞,而且應特別注意操作是否冪等。

POST操作可用於創建資源。POST 操作的明顯特徵是它不是冪等的。舉例而言,如果使用POST請求創建資源,而且啓動該請求多次,那麼每次調用後都會創建一個新的唯一資源。

GET操作必須是冪等的且不會產生意外結果。具體來講,帶有查詢參數的GET請求不應用於更改或更新信息(而應使用POST、PUT或PATCH)。

PUT操作可用於更新資源。PUT操作通常包含要更新的資源的完整副本,使該操作具有冪等性。

PATCH操作允許對資源執行部分更新。它們不一定 是冪等的,具體取決於如何指定增量並應用到資源上。例如,如果一個PATCH操作表明一個值應從A改爲B,那麼它就是冪等的。如果它已啓動多次而且值已是B,則沒有任何效果。對PATCH操作的支持仍不一致。例如,JavaEE7中的JAX-RS中沒有@PATCH註釋。

DELETE操作用於刪除資源。刪除操作是冪等的,因爲資源只能刪除一次。但是,返回代碼不同,因爲第一次操作將成功(200), 而後續調用不會找到資源(204)。

單一職責

簡明扼要的微服務設計原則,深入開發微服務,就從今天開始

 

設計原則很重要的一點就是簡單, 單一職責也就是我們經常所說的專人幹專事。

一個單元(一個類、函數或者微服務)應該有且只有一個職責。無論如何,一個微服務不應該包含多於一個的職責。職責單一的後果之一.就是職責單位(微服務、類、接口、函數)的數量劇增。據說Amazon、Netflix這些採用微服務架構的網站一個小功能就會調用幾十上百個微服務。但是相較於每個函數都是多個業務邏輯或職責功能的混合體的情況,維護成本還是低很多的。

SRP (單一職責原則)中的“單一職責”是個比較模糊的概念。對於函數,它可能指單一的功能,不涉及複雜邏輯;但對於類或者接口,它可能是指對單一對象的操作,也可能是指對該對象單一屬性的操作。總而言之,單一職責原則就是爲了讓代碼邏輯更加清晰,可維護性更好,定位問題更快的一種設計原則。

單一職責的優點如下:

  • 類的複雜性降低,實現什麼職責都有清晰明確的定義。
  • 可讀性提高,複雜性降低。
  • 可維護性提高,可讀性提高。

變更引起的風險降低,變更是必不可少的,如果接口的單一職責做得好,一個接口修改只對相應的實現類有影響,對其他的接口無影響,這對系統的擴展性、維護性都有非常大的幫助。

記得在三字經裏邊有這樣一段:

教之道,貴以專

說的就是無論學習還是構建團隊,最重要的是專才,而不是全才。就好比一個足球隊,如果都是前鋒或者都是後衛,那麼這樣的球隊一定不會出好成績,反而是將各個位置上的人進行統一協調,根據分工不同,共同協作,形成1+1>2的效果,那麼這樣的團隊就非常容易出好成績。

有很多公司爲了趕進度,經常會招聘- -些所謂的全能型人才,但是這種人往往專業程度不夠高,當遇到某些棘手的問題時,往往不能夠非常快速地解決問題。從而導致最終交付的軟件質量較差。

實施單一職責的目的如下:

  • 以類來隔離需求功能點,這樣當一個點的需求發生變化時,不會影響別的類的邏輯,這個和設計模式中的開閉原則類似,對於擴展持開放態度,對於修改持關閉態度。
  • 是一個原子模塊級的粒度,至於原子的粒度到底是什麼樣的,應該因業務而異,設計的過程中同時考慮業務的擴展,所以這就要求在設計的過程中,必須有業務專家共同參與,共同規避風險。
  • 粒度小,靈活,複用性強,方便更高級別的抽象。

每個微服務單獨運行在獨立的進程中,能夠實現松耦合,並且獨立部署。

微服務近幾年大火,裏面的核心知識更是數不勝數,小編這裏只是整理了一部分設計原則,後續小編會持續更新,保證朋友們每天接收新內容,每天進步一點點~~~

喜歡文章請多多點贊評論轉發,關注小編,你們的支持就是小編最大的動力!!!

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