go-ums 從需求分析到設計實現( v0.1.0 )

項目源碼地址 github.com/tsingson/go…html

文字有點長, 儘可能寫得簡單明瞭前端

文章歸納內容都寫上了, 因爲文檔進一步細化並補充更多需求後, 須要拆分爲設計文檔/接口文檔/測試文檔/評審文檔.....等等, 這裏再也不持續更新.java

後續補充變動, 請訪問 項目源碼地址mysql

x. update 更新 ( 2019/11/05)

因爲帶一個朋友學習 golang 開發, 因此, 這個項目正在重寫, 基本上, 本文提到的內容會所有變動, 主要變動以下:react

  1. 變動爲 step by step 的方式, 全新寫一個能夠商用的 ums 用戶管理子系統
  2. 後臺存儲變動爲默認支持 bbolt / postgres , 並提供接口, 對接 mysql ....
  3. 帶後臺管理 web 界面( 用 react ), 提供 gRPC ( probuf / flatbuffers 兩種) 與 RESTfull 管理/集成接口
  4. 支持 AAA 分佈式部分
  5. 附帶完整測試代碼

因爲是 step by step 給朋友演示開發過程, 因此, 大約分紅三個步驟開發:linux

  1. 建模, 在 /model 下完成存儲模型的基本處理, 包括用戶模型, 用戶狀態與用戶權限模型,與相關存儲
  2. 前端接口, 以及前端 web 實現, 前端模擬用戶端( http 與 TCP 兩種模式), 後端管理界面
  3. 實現分佈式 (附帶壓力測試)

架構變動以下:android

具體變動, 見 項目源碼地址git

0. go-ums 是什麼

go-ums 開發目標是一個開源項目, 核心由 golang 開發, 提供用戶管理(user-management-subsystem) / AAA 鑑權/受權/計賬 / 多業務會話共享與管理等, 以支持分佈式部署及雲部署爲主要目標github

這是一個從零開始的小項目, 持續漸進golang

reading-go 夜讀 相關 issue 討論中, 有個 gin 的練手項目, 有點意思.

這是一個相似的項目, 不一樣的地方是, 這個項目是以文檔開始的.

更多項目關聯文檔, 請訪問 github.com/tsingson/go… , 在 readme 中列示並持續添加中

先有文檔, 再寫代碼. 在文檔簡單說明一些個人設計套路

注: 這裏的設計, Design, 不限於架構設計, 程序設計, 也包含我的在攝影/印刷/書籍/海報中找出問題/解決問題的一些"套路".

先文檔, 後實施, 也是曾經做 SA/SE 的習慣了吧. 當年曾戲稱本身是 Simple Editor , 哈, 懷念那8年, 大鬍子, yaho BB, black more, 北京香山, 上海文廣,三角洲島.......

稍後在持續更新中一一道來, 看看橫向之間的有趣關聯.

1. 業務場景

不談業務需求, 與業務場景中的人兒們,再好的技術也難以落地變現.

這就是原始需求的收集/整理/清理/梳理, 是開發貫串始終的目標與仲裁準則:

  1. 是什麼? 有什麼價值?
  2. 是誰在用? 如何用( 業務操做流程)? 哪些是關鍵節點(不能省掉的業務行爲), 重點與難點是什麼?
  3. 在這些業務場景中, 邊界在哪裏( 哪些狀況是正常, 哪些是異常, 如何斷定, 什麼時間什麼狀況下有哪些處理方式)

從一個簡單而典型的業務場景開始, 來

1.1 業務場景/需求描述

這個開源項目是從 goim 在開源社區交流討論後, 在 reading-go 討論中偶然開始的

從業多年, 我的幾乎不在網絡上談論我的在 iT 技術職業經歷, 尤爲是項目細節, 這裏, 算是換個方式來公開談談吧

因此, 這裏也從 goim 做爲起點


不少朋友, 在閱讀 goim 源碼時, 都會感受到, 就算是 im 業務完整實施, 須要與用戶管理結合:

  1. 用戶註冊後, 提供一個用戶惟一標識, , 對應 goim 中的 mid
  2. 用戶認證, 讓用戶能夠長鏈接到 goim , 在認證成功時
    1. 提供一個 token , 該 token 中包含用戶能夠進入的房間列表
    2. 提供用戶發送 im 信息的入口地址( logic 部署多個狀況下)
  3. 用戶在 goim 中涉及會話的業務功能( 變動房間.....)

因此, 咱們能夠從上面描述到的, (不能省掉的) 基本業務功能開始

來, 來, 來 ...GO!

1.1.1 場景與流程簡述

( 省略)

稍後補充示意圖

1.1.2 業務指標(性能要求)

(簡化)

  1. 要求業務響應, 排除網絡延遲, 業務響應要求在 100ms 之內
  2. 支持10K tps 高併發
  3. 年度業務中斷時間低於5次, 業務中斷時間低於30分鐘
  4. 業務數據保留期限 1年
  5. 業務操做記錄要求支持審計

1.2.3 部署要求

(簡化)

  1. 服務器部署中國骨幹網絡IDC (電信網絡爲主, 廣州/上海兩地IDC ) 及美國骨幹網絡IDC ( 略)
  2. 以部署服務端優先支持 linux 與 docker
  3. 客戶端支持 windows / mac / linux 的 terminal 命令行, 支持主流瀏覽器( 當前市場佔80%的主流版本, 至關於 IE 10+)

1.2.4 開發/運維/運營要求

(省略)

1.2.5 成本要求

(省略)

1.2 feature list 需求列表

注, 如下按開發進度做了分組.

分組的意思, 就是排優先級, 排優先級便是排重要/緊急程度(按 SWOT Analysis 方式), 以決定前後處理順序.

1.2.1 prototype 開發需求 v0.1.0

用戶相關操做

  • 用戶註冊 register 用戶以 email + 密碼 註冊提交我的信息, 提交後驗證 email 是否存在惟一衝突, 若是沒有, 註冊成功( 分配用戶ID) 注意, 這裏隱藏着一個檢查用戶是否存在的操做
  • 用戶登陸與登出 login / logout 用戶以 email + passwrd 或 用戶名 + password 或 userID + password 能夠進行登陸, 登陸成功, 給用戶發送通行令牌 accessToken 注意, 這裏隱藏着一個檢查用戶登陸成功返回一個 access token 的操做
  • 用戶認證 authentication 針對具體業務, 用戶訪問具體業務時, 發送 access token 進行認證, 若是用戶認證成功, 能夠訪問指定業務, 不然拒絕. 通常來講, 用戶認證成功即表示建立一個合法的業務會話
  • 用戶通行令牌驗證 verify 用戶訪問指定業務時, 驗證 token 是否在有效期內, 以及相關受權是否有變動, 如不符合業務受權限制, 則拒絕提供服務

# 1.2.2 trial 試運行 v0.1.1

用戶相關操做

  • 用戶激活 active 用戶註冊後, 向用戶郵箱發送 email 驗證的激活郵件, 用戶從郵件中獲取激活碼後, 進行激活操做
  • 用戶登陸與登出 login / logout 用戶以 email + passwrd 或 用戶名 + password 或 userID + password 能夠進行登陸, 登陸成功, 給用戶發送通行令牌 accessToken
  • 用戶鎖定 suspend 禁止用戶業務消費行爲, 通常來講, 用戶在具體業務上, 會有指定的服務週期, 超出服務週期, 用戶被鎖定
  • 用戶恢復 resume 恢復用戶受權的業務行爲
  • 用戶刪除 deleted 用戶刪除本身或管理後臺刪除用戶, 注意, 在商用中, 用戶「刪除」通常意味着用戶狀態修改成 deleted 並中止全部訪問與全部業務, 但保留全部關聯數據( 這些關聯數據, 只有在必定期限後, 會手動或自動清除 purge )

2. 概要設計之模型設計

參照 1.2.1 小節, 很容易做一個簡單設計

2.1 數據模型

用戶對象名稱 account

  1. 用戶ID, 與 goim 配合, 就用 int64 吧, 一個全局惟一的正整數
  2. email , (簡化), 都是字符串, email 格式也不驗證, 其中 email 字符串長不得少於5個字符( >=5 ) ,
  3. password, (簡化) 都是字符串, 密碼不得少於6個字符( >= 6), 字符爲 a..zA..Z0..9$%-
  4. access tokdn 通告令牌, 也用字符串代替吧, 字符串長度 >=32 字符
  5. 用戶角色, 分別爲 非會員, 會員
  6. 用戶狀態, 分別爲註冊未激活, 已激活, 禁用, 已刪除
  7. 用戶建立時間, 簡單點, 用 int64 或 UTC timestamp
  8. 用戶信息變動時間, 簡單點, 用 int64 或 UTC timestamp

操做結果(狀態)定義

  1. transaction ID 事務惟一標識
  2. 狀態碼, 整數, 操做成功返回 200 / 操做失敗返回 500 / 請求接受並在處理中返回202
  3. 操做結果文本信息, 少於255字符, 操做成功, 文本信息, 要求標記業務操做名稱, 如 register ), 操做失敗, 返回失敗緣由( 文本信息 )

注: transaction ID 事務惟一標識, 支持異步操做, 以支持分佈式或集羣, 以及操做失敗時, 進行操做重試( 這樣可讓服務端處理上次操做失敗的數據, 例如進行清理, 或繼續使用, 以及在日誌中進行檢查/審計)

原型實現的約束與限制:

  1. 爲了快速實現原型, 用戶密碼直接存儲, 不加密
  2. 用戶ID , 直接用用戶建立的 utc 時間截( 納秒 )
  3. 簡化操做結果(狀態定義), 這裏先按 golang 實現習慣方式, 操做結果修改成 go 的 error 返回( 即 error = nil 或 != nil ) 注: 這個地方, 只是針對 go 的簡化

2.2 用戶操做與約束

(簡化)

  1. 用戶註冊 register ------> 調用 exists 檢查是否重複註冊, 若是不是, 建立用戶ID 並保存用戶信信息, 返回用戶數據( 不返回密碼), 返回操做結果狀態碼
  2. 檢查用戶是否重複存在 exists, 返回操做結果
  3. 用戶登陸 login ------> 以 email + pwd 登陸, 登陸成功, 建立並返回 access token, 返回操做結果狀態碼
  4. 用戶登出 logout -----> 清除 access token , 返回操做結果狀態碼
  5. 用戶認證 auth -------> 輸入用戶ID 或 token , 調用 verify 檢查 會話中的token 是否合法, 若是 token 合法則返回成功, 返回操做結果狀態碼
  6. 用戶令牌驗證 verify --------> 檢查 token 是否存在, 而且是否相等, 返回操做結果狀態碼

2.3 業務流程設計 (僅以 register 用戶註冊爲例)

2.3.1 register 用戶註冊

業務流程描述: 客戶端 ----------> 服務端, 進行用戶註冊, 發送註冊數據, 由服務器端返回註冊成功(獲取用戶ID ) 或失敗信息

----> 輸入:
  1. transaction ID 事務惟一標識
  2. email 合法郵箱地址
  3. password 密碼
----> 內部邏輯實現
  1. 檢查 email 是否重複( 即被成功註冊過), 判斷沒有重複, 則進行 2, 判斷有重複, 進行下說明 3
  2. 生成用戶 ID , 並保存到文件或數據庫, 保存成功, 返回成功結果輸出, 保存失敗, 進行下說明 3
  3. 處理錯誤輸出
  4. 以上處理, 每一步均以 事務 ID 與時間爲主鍵存日誌
----> 輸出
輸出 (成功, 返回用戶信息, 屏蔽密碼字段)
  1. account ID 用戶ID
  2. email
  3. 用戶角色
  4. 用戶狀態
  5. 建立時間
  6. 變動時間
輸出 (失敗, 返回事務標識, 錯誤狀態碼, 錯誤緣由文本)
  1. transaction ID 事務惟一標識
  2. 返回操做結果狀態碼
  3. 操做結果文本描述

2.3.2 接口設計

大白話:

接口就是兩個網元之間, 進行交互/通信的網絡協議/控制通訊命令(信令)/以約定格式傳輸相關數據(數據封裝)的簡稱

例如 web 瀏覽器與 web 服務器這兩個網元之間, 通常採用 HTTP 協議, 信令是 GET / POST / PUT / PATCH / DELETE ...., 數據封裝一般是以 MIME 來指定, 好比下面用到的 "application/json; charset=utf-8"

設計實現如下接口

  1. RESTful 接口 ( 描述省略, 見代碼)
  2. gRPC ( protobuf ) 接口 ( 略 )
  3. gRPC ( flatbuffers ) 接口( 對接 android java SDK , 詳細說明略)
  4. websocket 接口 ( 略 )
  5. TCP 接口 ( 略 )

接口設計, 事實是描述一下業務數據的輸入/輸出, 以及須要對接的兩端業務主體的業務過程(業務上如何進行交流與處理) 這裏簡化掉了, 並細化得很"編程化"了

2.3.2.1 RESTful 接口設計

關於 RESTful 接口, 相關推薦規範, 請自行查詢

這裏先簡要說明一下:

RESTful 一般是 HTTP + json 實現的接口, 其中

  1. 相似 /api/v1/account 這樣的 URI 就是一個接口, 其中 /api/v1 前綴只是輔助管理

    在下面咱們示例實現的用戶註冊接口, 能夠定義爲 /api/v1/register 或者 /xxx/yyyy 這樣你喜歡的方式

  2. HTTP 的 method 就是操做方式, 例如:

    • GET:讀取(Read)
    • POST:新建(Create)
    • PUT:更新(Update)
    • PATCH:更新(Update),一般是部分更新
    • DELETE:刪除(Delete)
  3. 數據編碼(序列化/反序列化) 是 "application/json; charset=utf-8」 標的 JSON 格式

  4. 少許操做關聯數據, 能夠在 HTTP header 中傳遞, 好比 transactionID/ token / cookie , 這些關聯數據, 通常用來協助狀態跟蹤

2.3.2.1.1 用戶註冊

對照 2.3.1 , 用戶註冊的接口, 能夠設計以下

--------->input請求

請求資源

POST 請求如下網址 http://localhost:3001/api/v1/register

request header

Context-Type:  "application/json; charset=utf-8"
 TransactionID: "201001419845668864"
複製代碼

request body

{
  "email": "test@email.com",
  "password": "201001419845668864"
}
複製代碼

--------->output返回

response header

Context-Type:  "application/json; charset=utf-8"
 TransactionID: "201001419845668864"
複製代碼

操做成功, 返回 http 狀態碼 200, 返回數據以下

response body

{
  "email": "test@email.com",
  "password": "201001419845668864"
}
複製代碼

操做失敗, 返回狀態碼 500, 返回數據以下

**

{
  "transactionID":"201001419845668864"
  "code": 500,
  "msg": "用戶Email已經被其餘用戶使用, 請選擇其餘email從新註冊"
}
複製代碼

其餘部分, 稍後補充.........

2.3.3 測試用例以下

  1. 檢查 email 無重複, 操做成功
  2. 檢查 email 有重複, 操做失敗
  3. 異常, 主要關注兩個, 保存失敗或異常, 通信異常中斷 (詳細說明, 省略)

3.概要設計之架構設計

先簡化爲如下架構做爲驗證原型開發

client ( 多個) <----> gateWay( HA熱備, 支持路由/分流等) <-----> AAA (本地緩存, 多個部署)<-------> UMS ( 雙機熱備)

其中:

  • client 到 AAA 首先實現 RESTful
  • AAA 到 UMS 之間, 選擇 gRPC + flatbuffers
  • UMS 後存儲, 選擇 redis + postgreSQL

稍後補充.........

4. 詳細設計

4.1 設計目標與原則

因爲需求緣由, 咱們須要考慮達成如下目標:

  • 低延遲, 高容量, 高併發
  • 可擴展的多點部署, 雲部署

因此, 先拍腦殼隨意定義一下要實現目標, 以下所示. 接下來, 再評估哪些真正須要, 優先級, 以及具體實現方案

  • 網元之間無狀態
  • 線程之間無鎖
  • 儘量快的網元間接口通信
  • 儘量減小接口之間數據序列化/反序列化的次數, 加快接口之間數據序列化/反序列化的效率
  • 網元支持按需動態擴展或收縮部署, 簡單點, 就是網元健康檢查 + 路由 + 分流可控制
  • 支持 QOS 控制, 先支持限流

4.2 設計實現 ( golang 爲例)

稍後補充說明部分

4.2.1 模型的實現

用戶模型與操做的 golang 實現

見 [github.com/tsingson/go…]

(說明省略)

4.2.2 接口設計的實現

見 [github.com/tsingson/go…]

(說明省略)

4.2.3 業務邏輯實現

github.com/tsingson/go…

(說明省略)

4.2.4 UT ( Unit Test) 單元測試

測試用例以下

  1. 檢查 email 無重複, 操做成功
  2. 檢查 email 有重複, 操做失敗
  3. 其餘異常( 略)

見 /pkg/service 下測試代碼

4.3 LIT ( local integration test) 網元集成測試

見 /pkg/web 下各測試代碼

4.4 SIT ( system intergration test ) 系統集成測試

見 /cmd/cli 下代碼

稍後補充..........

4.5 編譯/部署/運維

參見 go-ums v0.1.0 測試/編譯/運行

稍後補充.............

5. 性能測試/部署測試/ trial 驗證

省略 ...

6. 附註/參考

6.1 接口設計相關參考

_

_

關於我

網名 tsingson (三明智, 江湖人稱3爺)

原 ustarcom IPTV/OTT 事業部播控產品線技術架構溼/解決方案工程溼角色(8年), 自由職業者,

喜歡音樂(口琴,是第三/四/五屆廣東國際口琴嘉年華的主策劃人之一), 攝影與越野,

喜歡 golang 語言 (商用項目中主要用 postgres + golang )

_

題圖: 2018/12/24 香港黑白攝影展前, 與深圳影友在香港街頭

_

tsingson 寫於中國深圳

小羅號口琴音樂中心, 2019/05/11

相關文章
相關標籤/搜索