当前位置:网站首页>Go 微服务开发框架DMicro的设计思路
Go 微服务开发框架DMicro的设计思路
2022-08-01 22:08:00 【ClownFish】
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协议,自定义CodecHook点,插件系统,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 V6Unix SocketKCPQUIC
支持对连接的性能调优.
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吧!
边栏推荐
猜你喜欢

HCIP---Multiple Spanning Tree Protocol related knowledge points

Flutter基础学习(一)Dart语言入门

用户体验 | 如何度量用户体验?

感觉自己好傻

小程序容器+自定义插件,可实现混合App快速开发

render-props and higher order components

JS prototype hasOwnProperty in 加方法 原型终点 继承 重写父类方法

SOM Network 2: Implementation of the Code

联邦学习在金融领域的发展和应用

SOM Network 1: Principles Explained
随机推荐
企业公众号文章写作方向:如何写出读者认可的优质内容
字符串——Trie
Kubernetes Scheduler全解析
迁移学习——Discriminative Transfer Subspace Learning via Low-Rank and Sparse Representation
高等代数_证明_矩阵的行列式为特征值之积, 矩阵的迹为特征值之和
Still struggling with reporting tool selection?To take a look at this
如何给 UE4 场景添加游戏角色
一种灵活的智能合约协作方式
不卷了!入职字节跳动一周就果断跑了。
(*゚ヮ゚)*【精品C语言整理】*(゚ヮ゚*)女盆友缠着你让你教她写代码怎么办?安排,三万字博文带你走遍C语言,从此不再害怕编程
今日睡眠质量记录74分
0DFS Medium LeetCode6134. Find the closest node to the given two nodes
ImportError: `save_weights` requires h5py.问题解决
Small program -- subcontracting
xctf攻防世界 Web高手进阶区 web2
自建 Prometheus 采集腾讯云容器服务监控数据最佳实践
How to prevent governance attacks in DAOs?
_ _ determinant of a matrix is higher algebra eigenvalue of the product, the characteristic value of matrix trace is combined
线程池分析
解决 win10 下 ISE14.7的 iMPACT 崩溃问题 - FPGA 笔记