当前位置:网站首页>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吧!
边栏推荐
猜你喜欢

Recycling rental system 100% open source without encryption Mall + recycling + rental

如何给 UE4 场景添加游戏角色

论文解读(GSAT)《Interpretable and Generalizable Graph Learning via Stochastic Attention Mechanism》

AIDL communication

使用Jenkins做持续集成,这个知识点必须要掌握

【ASM】字节码操作 MethodWriter

【Verilog刷题篇】硬件工程师从0到入门1|基础语法入门

联邦学习入门

Centos7--MySQL的安装

第一讲 测试知多少
随机推荐
Based on php online music website management system acquisition (php graduation design)
【移动Web】移动端适配
Based on php online learning platform management system acquisition (php graduation design)
【C语言】猜数字小游戏
将vim与系统剪贴板的交互使用
selenium无头,防检测
恒星的正方形问题
联邦学习在金融领域的发展和应用
Lecture 3: Several common table field data types in MySQL database
迁移学习——Discriminative Transfer Subspace Learning via Low-Rank and Sparse Representation
Centos7--MySQL的安装
The thing about npm
线上故障排查方案
Recycling rental system 100% open source without encryption Mall + recycling + rental
SAP Spartacus NgExpressEngineDecorator 的工作原理
威纶通触摸屏如何打开并升级EB8000旧版本项目并更换触摸屏型号?
Small program -- subcontracting
365天挑战LeetCode1000题——Day 046 生成每种字符都是奇数个的字符串 + 两数相加 + 有效的括号
Based on php tourism website management system acquisition (php graduation design)
论文解读(GSAT)《Interpretable and Generalizable Graph Learning via Stochastic Attention Mechanism》