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