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