1. 程式人生 > >微服務設計方法

微服務設計方法

概述

服務就是代表特定功能的軟體實體, 是不依賴於任何上下文或外部服務的自治構件.微服務設計就是軟體設計的一個子範疇, 它主要是指如何設計這樣的服務來滿足需求, 而這個服務是微小且自治的, 滿足微服務的若干特徵。

先看看傳統軟體設計的流程: 需求分析--概要設計--詳細設計。

軟體設計

需求分析和整理

對需要做詳細的分析, 一是功能性需求

功能性需求:

  • 用例
  • 場景
  • 驗收測試用例

非功能性需求:

  • 高可用性
  • 高效能
  • 伸縮性
  • 擴充套件性
  • 伸縮性
  • 安全性
  • 穩定性
  • 健壯性
  • 可測試性

以使用者登入與註冊為例, 我們來分析其用例 Use case 和使用者故事 User Story

用例 Use case

除了使用繪圖工具和畫用例圖, 還有幾種方法通過指令碼來生成用例圖

一是使用線上網站 yuml.me

https://yuml.me/608ca377

  use case

UML 生成指令碼如下

[User]-(Sign In)
[User]-(Sign Out) [User]-(Sign Up) [User]-(Forget Password) [User]-(Change Password) (Sign In)>(Remember Me) (Sign Up)>(Send Verification Email) (Forget Password)>(Send Reset Password Email) (Change Password)<(Send Reset Password Email) [Admin]^[User] [Admin]-(Add User) [Admin]-(Delete User) [Admin]-(Lock User) [Admin]-(Change Password Policy) 

二是使用是通過 plantuml 來生成

http://plantuml.com/ 上下載 plantuml.jar , 然後用如下命令生成用例圖

java -jar plantuml.jar usecase.txt

示例UML 生成指令碼如下

@startuml

User -> (Sign In)
User --> (Sign Out) 
User --> (Sign Up)
User --> (activate)
User --> (forget/reset password)
:Admin: ---> (lock user)
:Admin: ---> (add user) 
:Admin: ---> (delete user) 

@enduml

三是使用graphviz

先安裝graphviz, 再執行如下命令

dot usecase1.gv -Tpng -o usecase1.png

示例UML生成指令碼如下

digraph G {
    rankdir=LR;

    subgraph clusterUser {label="User"; labelloc="b"; peripheries=0; user};
    
    user [shapefile="stick.png", peripheries=0]; signin [label="Sign In", shape=ellipse]; signout [label="Sign Out", shape=ellipse]; signup [label="Sign Up", shape=ellipse]; user->signin [arrowhead=none]; user->signout [arrowhead=none]; user->signup [arrowhead=none]; } 

使用者故事 User Story

User Story 講究 INVEST 原則

  • "I" ndependent (of all others) 獨立的
  • "N" egotiable (not a specific contract for features) 可協商的
  • "V" aluable (or vertical) 有價值的
  • "E" stimable (to a good approximation) 可估量的
  • "S" mall (so as to fit within an iteration) 足夠小的
  • "T" estable (in principle, even if there isn't a test for it yet) 可測試的

以使用者註冊 Sign Up 為例, 可以拆分為如下子使用者故事

  1. 作為一個未註冊使用者, 我想輸入我的電子郵件地址和密碼,註冊到站點

1.1 我必須輸入合法和郵件地址,符合密碼策略的密碼以及一致的驗證碼進行註冊
預設的密碼策略是最低8個字元, 必須包含大小寫字母和至少一個數字

# Story Priority Estimation Deadline Comments
1.1.1 生成驗證碼 P3 2 MD 2018-10-15 防光學識別
1.1.2 顯示登錄檔單 P1 1 MD 2018-10-10  
1.1.3 郵件地址格式驗證 P1 1 MD 2018-10-10 客戶端和服務端都要驗證
1.1.4 比較兩次輸入的密碼是否相同 P1 2 M
H 2018-10-10  
1.1.5 驗證密碼是否符合密碼策略 P2 1 MD 2018-10-10  
1.1.6 驗證輸入的驗證碼 P3 2 MD 2018-10-12  
1.1.7 檢查是否已有相同的郵件地址存在 P1 1 MD 2018-10-12  
1.1.8 輸入驗證無誤後存入資料庫,狀態為pending P2 2 MD 2018-10-13  
1.1.9 生成此使用者的啟用連結 P2 2 MD 2018-10-15  
1.1.10 向註冊郵箱傳送一封確認郵件 P2 2 MD 2018-10-15  

1.2 我的註冊郵箱會收到一封驗證郵件, 提示我點選註冊連線, 從而啟用我的註冊帳戶

1.3 當我完成啟用後會自動跳到站點的首頁, 提示我進行登入

概要設計

基於上面所定義的驗收測試用例, 進行軟體服務的總體設計,

先劃分模組,以及模組之間的關係和互動.

先讓我們來看看微服務的典型架構 -- 六邊形架構(Hexagonal Architecture),又稱為埠和介面卡架構風格

傳統的分層架構我們非常熟悉

  1. 表現層
  2. 業務層
  3. 資料層

而六邊形架構更加強調對外提供服務的介面適配


   
  1. 領域層(Domain Layer):位於最內層的核心層,純粹的核心業務邏輯,一般不包含任何技術實現或引用。
  2. 埠層(Ports Layer):領域層之外,負責接收與用例相關的所有請求,這些請求負責在領域層中協調工作。埠層在埠內部作為領域層的邊界,在埠外部則扮演了外部實體的角色。
  3. 介面卡層(Adapters Layer):埠層之外,負責以某種格式接收輸入、及產生輸出。

詳細設計

詳細設計就是把總體設計落到實處, 一般我們會繪製如下的 4+1 檢視

   
  1. 邏輯檢視(Logical View),設計的物件模型。
  2. 程序檢視(Process View),捕捉設計的併發和同步特徵。
  3. 部署檢視(Deployment View),描述了軟體到硬體的對映,反映了分散式特性。
  4. 實現檢視(Implementation View),描述了在開發環境中軟體的靜態組織結構。

四加一的一是指我們之前提到的用例檢視

  1. 用例檢視(Use-Case View),該檢視是其他檢視的依據

領域驅動服務設計

軟體的領域有多廣, 微服務的領域就有多廣. 基本上我們可分為兩大類

  1. 非功能領域的通用服務

它指對應於非功能需求的, 通用的, 可重用的服務型別, 比如系統認證服務, 快取服務, 資料儲存服務, 以及在雲平臺上常用的註冊服務, 分散式鎖服務, 訊息佇列服務等等

微服務構建有其自身特點, 尤其是相比單體服務, 分散式系統使得我們在容錯和高可用方面必須考慮周詳, 有些共通的原則, 模式和實踐, 我們在系統設計需要熟練掌握, 並在實踐中不斷根據度量資料進行演進和調優.

這些和具體的業務關係不大, 無論你是做電商的 還是做網路會議的, 基本上都會用到.

  • 服務註冊和發現
  • 服務閘道器和編排
  • 服務度量和基於度量的自動化運維
  • 服務安全,跟蹤和審計
  • 服務可用性相關模式: 分流, 限流, 斷流
  • 等等

這些通用模組之後再展開來講

  1. 業務功能領域的專用服務

技術經常更新換代,語言層出不窮,這些都會過時, 淘汰和更新換代, 可以業務邏輯及商業模型不會輕易廢棄,因為它是企業安身立命,生存和賺錢的根本,需要小心維護,應使用者的需求,企業未來的發展而增強和改進。

而商業模型和業務邏輯如何能對映到軟體系統中呢?答案就是領域模型,它是軟體設計的核心,指導著我們如何實現,如何編碼。

所謂領域主要就是指業務邏輯,規則和流程所對應的的軟體設計模型,對於那些重要的,複雜的業務模型稱為核心域,相對次要的模型稱為支撐子域,這些領域都有一個邊界上下文,使用一種通用語言來描述, 而領域的邊界,彼此之間的關係以及整合方式使用上下文對映圖來表示.

領域驅動設計概述

領域驅動設計採用的架構不一而足,視具體案例情況而定。比如分層架構,埠和介面卡,SOA,REST,CQRS,事件驅動(管道和過濾器,長時間處理過程,事件源)

領域模型的基礎是實體和值物件,而對於它們的處理以及流程控制更適合用領域服務來表示,而領域事件在不同的服務和系統之間用於整合和互動很有用。以模組來劃分領域物件,以聚合來整合相關的物件,以工廠來建立物件,以資源庫來存取物件,這些都是領域驅動設計中的核心。

每個領域都有其專有的知識體系和業務場景, 服務必然是針對某個業務場景, 直接或者間接地為業務提供服務

  1. 使用通用語言
    在領域專家和技術人員之間使用統一的語言來描述業務邏輯, 使用規範統一的術語,協議,各種文件和圖表

  2. 做好領域的劃分和建模
    領域可分為

  • 核心子域:核心的業務邏輯和流程
  • 支撐子域:支援核心業務的運轉
    *通用子域: 基礎設施和通用的工具或管理系統, 比如安全驗證, 使用者管理等
  1. 對領域物件進行細分
  • 分析聚合根實體
  • 識別根實體和範圍和邊界
  1. 定義限界上下文
  • 根據業務場景,領域的劃分來定義系統和邊界和上下文
    微服務與上下游服務的互動與依賴關係

微服務設計模板

1. 總體介紹

1.1 需求
1.1.1 業務需求和目標
需求分析, 使用者場景及用例圖

1.1.2 技術需求: 容量需求,高可用性,安全性,伸縮性

1.2 背景
1.2.1 業務背景
1.2.2 技術背景: 當前架構, 容量, 侷限和效能瓶頸

2. 設計

2.1 總體架構
總體框圖

2.2 備選方案

2.3 領域設計
主要的領域物件, 流程以及實體關係圖

2.4 範圍與影響
所影響的範圍以及對於其他上下游元件的影響

2.5 詳細設計

2.5.1 介面描述
2.5.2 邏輯描述
2.5.3 資料結構
2.5.4 侷限與限制
2.5.5 效能問題
2.5.6 設計約束
2.5.7 意外情況處理

3. 依賴條件

3.1 平臺
3.2 資料庫
3.3 其他服務及其 SDK

4. 部署

4.1 配置
4.2 安裝
4.3 部署及驗證

5. 度量

5.1 關鍵因素 KPI
5.2 度量設計
5.3 度量工具

6. 測試方案

6.1 測試用例
6.2 API 測試方案
6.3 整合測試和端到端測試方案
6.4 效能測試方案

7. 問題與風險

當前存在的問題與可能存在的風險

8. 參考文件和連結