網站首頁 編程語言 正文
背景
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 的 id -
Name
?返回編 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
?設置鏈接讀緩沖區 size -
SetWriteBuffer
?獲取鏈接寫緩沖區 size -
SetNoDelay
?開啟關閉 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
?吧!
原文鏈接:https://juejin.cn/post/7155400238981709831
相關推薦
- 2023-02-27 python定時任務timeloop庫用法實例詳解_python
- 2022-07-03 Android利用貝塞爾曲線繪制動畫的示例代碼_Android
- 2022-05-10 ASP.NET?Core使用Log4net實現日志記錄功能_實用技巧
- 2022-10-09 Python?局部變量global詳解_python
- 2022-04-20 C++的數據類型你真的了解嗎_C 語言
- 2022-04-20 從0編寫區塊鏈之用python解釋區塊鏈最基本原理_python
- 2022-12-24 c++重載運算符時返回值為類的對象或者返回對象的引用問題_C 語言
- 2022-12-22 Android開發input問題解決分析_Android
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支