Go 微服務開發框架DMicro的設計思路
Go 微服務開發框架DMicro
的設計思路
DMicro
原始碼地址:
背景
DMicro
誕生的背景,是因為我寫了10來年的PHP,想在公司內部推廣Go
,公司內部的元件及rpc協議都是基於swoole
定製化開發的。調研了市面上的各種框架,包括beego
,goframe
,gin
,go-micro
,go-zero
,erpc
等等,可能是我當時技術能力有限,並不能讓這些框架很好的適配我們的業務。
我們業務開發有幾個痛點,在當時golang
的生態中無法找到一整套解決方案。
- 微服務應用和單體應用同時開發。
- 高效能,高可用的網路通訊。
- 需要自定義應用層的協議(重點)。
- 需要靈活的外掛擴充套件機制,方便適配現有系統(重點)。
- 服務端與客戶端的概念模糊,互相都能使用相同的api呼叫對方。
- 支援Push訊息。
- 連線/會話管理。
- 高效率的開發,支援通過proto生成程式碼。
- 支援多種網路協議,
tcp
,websocket
,quic
,unixsocket
. - 相容http協議。
- 能夠更快速的定位問題。
- 更便捷的增加新特性。
在對常用的開源框架做了簡單的調研以後,發現並沒有一款合適的框架能滿足我的所有需求。在認真思考過後,發現erpc
和goframe
兩個框架的結合體能滿足我的需求,於是就誕生了自研DMicro
.
概述
DMicro
中的drpc
元件的思想是參考erpc
實現,甚至可以說是它的繼承者。
drpc
元件是DMicro
框架的一部分,為了適配DMicro
框架,在erpc
的基礎上做了深入的擴充套件開發。
整個DMicro
大量使用goframe
中的元件,如果業務使用goframe
框架,可以無縫接入。
DRpc
特性列表:
對等通訊
,對等Api
高效能
,非阻塞非同步IO
自定義Proto
,,相容http協議
,自定義Codec
Hook點
,外掛系統
,Push訊息
,session管理
,Socket抽象
,斷線重連
,過載保護
,負載均衡
,心跳機制
,平滑重啟
...
DServer
特性列表:
快速構建
,平滑重啟
,多程序支援
,單/多程序一致
預定義命令列
,ctrl命令管理服務
可觀測
,可控制
,應用沙盒
DMicro
已經內建元件:
- [x]
Registry
服務註冊 - [x]
Selector
服務發現 - [x]
Eventbus
事件匯流排 - [x]
Supervisor
程序管理 - [ ]
Code gen
程式碼生成 - [ ]
Tracing
鏈路追蹤 - [ ]
Metrics
統計告警 - [ ]
Broker
限流熔斷 - [ ]
OpenAPI
文件自動生成
架構
設計理念
對DMicro
框架的設計,從設計之初就是在追求靈活性,適應性。在保證微服務的穩定性前提下,追求專案的開發效率。
- 面向介面設計,保證程式碼穩定,提供靈活定製。
- 抽象各元件的介面,高內聚,低耦合。
- 分層設計,自上而下逐層封裝,利於穩定和維護。
- 高效能,高可用,低消耗。
- 對開發友好,封裝複雜度。
- 提供豐富的元件及功能,讓開發專注業務。
無數個寫DMicro
的日夜,我都謹記開發三原則:
Clarity(清晰)
Simplicity(簡單)
Productivity(生產力)
無論工作,還是做開源專案,都應該保持這三個原則,養成良好的習慣。
面向介面設計
DMicro
秉承著萬物皆介面的原則,提供框架無與倫比的擴充套件性.
下圖展示的是訊息的傳送的流轉流程,可以看到,所有的功能點都被抽象成了介面,每個功能點都提供了不同的實現.
會話 Session
大多數的Rpc
框架並不強調會話(session
)的概念,因其應用場景不需要用到會話(session
). 那麼drpc
為什麼需要抽象出會話(session
)呢?
Endpoint
融合了Client
和Server
,需要提供相同的Api
.服務端
需要主動向客戶端
傳送訊息,並且獲取客戶端的響應.服務端
支援對多個客戶端
批量傳送訊息.- 非同步主動斷開
一個
或多個
會話. - 獲取會話底層的
檔案描述符
,對其進行效能調優. - 可以為每個會話繫結特殊的
資料/屬性
.
Session
抽象了整個drpc
框架的會話,把Socket
,Message
,Context
都融合到一起. 開發者只需要對session
進行操作,就能實現大多數需求.
- 獲取連線資訊
- 控制連線的生命週期(超時時間)
- 控制單次請求的生命週期(超時時間)
- 接收訊息
- 傳送訊息
- 建立訊息的上下文
- 繫結會話的相關資訊(如使用者資訊)
- 斷線重連
- 主動斷開會話.
- 健康檢查
- 獲取連線關閉事件
- 為會話設定單獨的id
Session
介面可以細分為4個interface{}
,分別是EarlySession
,BaseSession
,CtxSession
,Session
. 對應的是應用的不同生命階段會話(Session
)擁有的不同屬性.
EarlySession
表示剛生成會話,尚未啟動 goroutine 讀取資料的階段.BaseSession
只有最基礎的方法,用於關閉連線時候的外掛引數.CtxSession
在處理程式上下文中傳遞的會話物件.Session
全功能的會話物件.
正常情況下,開發者用到的都是Session
,CtxSession
這兩個介面,其他2個介面是在外掛中使用.
訊息 Message
訊息Message
包含訊息頭Header
,訊息體Body
,是客戶端與服務端之間通訊的實體.
Message interface{}
抽象了對通訊實體的操作.
Size
訊息的長度Transfer-Filter-Pipeline
報文資料過濾處理管道Seq
序列號MType
訊息型別ServiceMethod
資源識別符號Meta
訊息的元資料BodyCodec
訊息體編碼格式Body
訊息體
協議 Proto
協議是對訊息Message
物件的序列化和反向序列化,框架提供Proto
介面. 只需要實現該介面,開發者就能定製符合業務需求的自定義協議,從而提升了框架的靈活性.
介面的定義如下:
type Proto interface {
Version() (byte, string)
Pack(Message) error
Unpack(Message) error
}
Version()
返回該協議的id和名字,兩個組成唯一的版本號.Pack
對訊息Message
物件進行序列化.Unpack
對位元組流反序列化,生成一個訊息Message
物件.
目前框架已支援Http
,Json
,Raw
,Protobuf
,JsonRpc
這5個協議.
RAW
協議組成如下:
其他協議可以參考程式碼.
編碼 Codec
作為一個通用性的框架,支援的協議可以有多種,訊息體的編解碼也可以有多少種. drpc
使用Codec
介面對訊息體Body進行編解碼.
介面的定義如下:
type Codec interface {
ID() byte
Name() string
Marshal(interface{}) ([]byte, error)
Unmarshal([]byte, interface{}) error
}
ID
返回編Codec的idName
返回編Codec的名字,名字是為了開發者更容易識別.Marshal
對訊息內容進行編碼Unmarshal
對訊息內容進行解碼
目前框架已支援Form
,Json
,plain
,Protobuf
,XML
這5個編解碼.
連線 Socket
Socket
擴充套件了net.Conn
,並且抽象出介面,方便框架對底層網路協議的整合.
Socket
介面實現了一部分Session
介面的功能,Session
介面呼叫的一些方法,實際上是轉發呼叫了Socket
中的方法.
這樣的分層實現,讓Socket
擁有的整合其他協議的能力.
TCP V4
,TCP V6
Unix Socket
KCP
QUIC
支援對連線的效能調優.
SetKeepAlive
開啟連結保活SetKeepAlivePeriod
連結保活間隔時間SetReadBuffer
設定連結讀緩衝區sizeSetWriteBuffer
獲取連結寫緩衝區sizeSetNoDelay
開啟關閉no delay演算法ControlFD
支援操作連結的原始控制代碼
有機的組合
前面講到,DMicro
框架萬物皆介面,分層+介面的設計,讓DMicro
有了靈活的組成高效且符合業務實際情況的能力.
接下來我們要講到實現這些能力的基礎.外掛系統.
外掛 Plugin
外掛系統給框架帶來了極大的擴充套件性和靈活性,是整個框架的一個靈魂模組,有了它,框架就有了無限可能。
什麼樣的外掛系統才能算是優雅呢?我能想到的有以下幾點:
- 合理且豐富的
hook
位置,能夠覆蓋整個框架的生命週期,貫穿通訊的各個環節。 - 每個
hook
位置的入參和出參都是經過精心設計。 - 每個外掛都能夠使用多個
hook
位置,每個hook
位置都能被多個外掛使用。 - 設計的足夠簡潔,優雅。能方便的進行二次開發定製。
在drpc
中,鉤子貫穿與整個Endpoint
的生命週期,是它不可或缺的重要一環。
通過這些
鉤子 Hook
點,賦予了外掛無限可能.
元件
有了外掛,就能通過外掛的組合,編寫綜合功能的元件,目前框架提供一些內建的元件,
服務端 Rpc Server
客戶端 Rpc Client
服務註冊 Registry
服務發現 Selector
事件匯流排 EventBus
程序管理 Supervisor
即將提供:
鏈路追蹤 Tracing
統計告警 Metrics
限流熔斷 Broker
.
限於篇幅的原因,具體元件的實現,這裡就不深入講解,請關注後續的文章.
未來展望
如果把DMicro
比作人生,現在成長的階段還處在少年時期,只完成了基礎的架構設計和一部分元件的開發.
接下來的方向主要是往易用性和可靠性方向發展.
易用性:
- 專案效能工具
dmctl
工具的開發,包括程式碼生成,專案結構生成,打包,編譯等等功能. - 符合openapi定義的文件元件的開發.
- 更加完善的文件和使用示例.
可靠性:
- 可觀測性
- 鏈路追蹤
- 指標資訊
- 日誌流
- 生產可用
- 測試用例的完善
- 程式碼覆蓋率
- 效能調優
希望DMicro
能在大家的呵護及鞭策下茁長成長.
開源不易,需要更多小夥伴加入,共創DMicro
. 如果你希望使用DMicro
,趕快引入程式碼,搭建你的第一個新專案吧! 如果你也想為DMicro
生態添磚加瓦,趕快Fork
程式碼,給我們提交pr
吧!