日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Go?微服務開發框架DMicro設計思路詳解_Golang

作者:退休程序猿 ? 更新時間: 2022-11-27 編程語言

背景

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

欄目分類
最近更新