Go 微服务开发框架 DMicro 的设计思路

  Go 微服务开发框架 DMicro 的设计思路

DMicro 源码地址:

  • Gitee:
  • dmicro: dmicro是一个高效、可扩展且简单易用的微服务框架。包含drpc,dserver等

背景

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 能在大家的呵护及鞭策下茁长成长.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/780.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

多模态特征融合:图像、语音、文本如何转为特征向量并进行分类

多模态特征融合前言输入层,数据集转为特征向量图像语音什么是时域信号,什么是频域信号语音信号转换 - 1.傅立叶变换语音信号转换 - 2.梅尔频率倒谱系数文本词袋模型词嵌入模型输出层,多模态模型合并前言 学习多模态的话题可以从深度学习的分…

【YOLOv8/YOLOv7/YOLOv5/YOLOv4/Faster-rcnn系列算法改进NO.57】引入可形变卷积

文章目录前言一、解决问题二、基本原理三、​添加方法四、总结前言 作为当前先进的深度学习目标检测算法YOLOv8,已经集合了大量的trick,但是还是有提高和改进的空间,针对具体应用场景下的检测难点,可以不同的改进方法。此后的系列…

[JS与链表]普通链表

为什么要用链表要储存一系列数据,最常用的数据结构是数组。数组有个缺点就是在中间插入或删除元素需要移动元素,成本很高。什么是链表链表也是有序元素的集合结构。链表中的元素在内存中并不是连续放置的。每个元素都可以理解为一个对象。包含了本身元素…

简单了解JSP

JSP概念与原理概念: Java Server Pages,Java服务端页面一种动态的网页技术,其中既可以定义 HTML、JS、CSS等静态内容,还可以定义Java代码的动态内容JSP HTML Java, 用于简化开发JSP的本质上就是一个ServletJSP 在被访问时,由JSP容…

博途PLC开放式以太网通信TRCV_C指令应用编程(运动传感器UDP通信)

博途PLC开放式以太网通信TSENG_C指令应用,请参看下面的文章链接: 博途PLC 1200/1500PLC开放式以太网通信TSEND_C通信(UDP)_plc的udp通信_RXXW_Dor的博客-CSDN博客开放式TSEND_C通信支持TCP 、UDP等,关于TSEND_C的TCP通信可以参看下面这篇文章:博途PLC 1200/1500PLC开放式…

opencv识别车道线(霍夫线变换)

目录1、前言2、霍夫线变换2.1、霍夫线变换是什么?2.2、在opencv中的基本用法2.2.1、HoughLinesP函数定义2.2.2、用法3、识别车道3.1、优化3.1.1、降噪3.1.2、过滤方向3.1.3、截选区域3.2、测试其它图片3.2.1、代码3.2.2、图片13.2.3、图片23.2.4、图片31、前言 最近…

C++模拟实现红黑树

目录 介绍----什么是红黑树 甲鱼的臀部----规定 分析思考 绘图解析代码实现 节点部分 插入部分分步解析 ●父亲在祖父的左,叔叔在祖父的右: ●父亲在祖父的右,叔叔在祖父的左: 测试部分 整体代码 介绍----什么是红黑树 红…

2023年江苏省职业院校技能大赛中职网络安全赛项试卷-教师组任务书

2023年江苏省职业院校技能大赛中职网络安全赛项试卷-教师组任务书 一、竞赛时间 9:00-12:00,12:00-15:00,15:00-17:00共计8小时。 二、竞赛阶段 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 第一阶段 基础设施设置与安全加固、网络安全事件响应、数…

链表相关oj题

1.Leetcode203 移除链表元素 解题思路:从头节点开始进行元素删除,每删除一个元素,需要重新链接节点 struct ListNode* removeElements(struct ListNode* head, int val){struct ListNode*dummyheadmalloc(sizeof(struct ListNode));dummyhea…

spring5(四):IOC 操作 Bean 管理(基于注解方式)

IOC操作Bean管理(基于xml方式)前言一、注解1、概述二、入门案例1、Bean 的创建2、Bean的自动装配2.1 Autowired2、Qualifie3、Resource4、Value3、扫描组件3.1 配置文件版3.2 注解版4、测试前言 本博主将用CSDN记录软件开发求学之路上亲身所得与所学的心…

Mysql常用命令

mysql连接: [roothost]# mysql -u root -p Enter password:******创建数据库: CREATE DATABASE 数据库名; 删除数据库: drop database 数据库名; 使用mysqladmin删除数据库: [roothost]# mysqladmin -u root -p dr…

【数据结构】链表OJ(二)

Yan-英杰的博客 悟已往之不谏 知来者之可追 目录 一、反转链表 二、合并两个有序链表 三、链表分割 四、链表的回文结构 一、反转链表 输入:head [1,2,3,4,5] 输出:[5,4,3,2,1] 输入:head [1,2] 输出:[2,1] 示例 3&#xf…

Vulnhub靶场----10、LazySysadmin

文章目录一、环境搭建二、渗透流程一、环境搭建 DC-7下载地址:https://download.vulnhub.com/dc/DC-9.zip kali:192.168.144.148 DC-9:192.168.144.157 二、渗透流程 1、信息收集nmap -sV -sT -p- -T4 192.168.144.157思路: 1、80…

基于vivado(语言Verilog)的FPGA学习(3)——FPGA理论知识

基于vivado(语言Verilog)的FPGA学习(3)——FPGA理论知识 文章目录基于vivado(语言Verilog)的FPGA学习(3)——FPGA理论知识1. FPGA介绍1.1.FPGA内部结构(1). 可…

【云原生|Docker】01-docker简介

目录 前言 Docker简介 1. 什么是docker 2. Docker和vm有什么区别 3. Docker架构 4. Docker特性 Docker安装 1. Docker版本介绍 2. Centos7安装docker 3. Docker校验 4. Docker启动 5. Docker配置文件 前言 接下来准备记录云原生系列的相关知识&#x…

Linux防火墙的关闭

查看防火墙的状态打开终端输入如下命令systemctl status firewalld如图所示:running表示防火墙目前处于打开状态输入命令进行关闭防火墙:systemctl stop firewalld如图所示正常的用户是没有权限的,需要输入管理员的密码才能够进行关闭防火墙。…

OpenAI GPT-4震撼发布:多模态大模型

OpenAI GPT-4震撼发布:多模态大模型发布要点GPT4的新功能GPT-4:我能玩梗图GPT4:理解图片GPT4:识别与解析图片内容怎样面对GPT4申请 GPT-4 API前言: 🏠个人主页:以山河作礼。 📝​📝:本文章是帮助大家更加了…

中国版的“ChatGPT”狂飙的机会或许要出现了

⭐️我叫忆_恒心,一名喜欢书写博客的在读研究生👨‍🎓。 如果觉得本文能帮到您,麻烦点个赞👍呗! 近期会不断在专栏里进行更新讲解博客~~~ 有什么问题的小伙伴 欢迎留言提问欧,喜欢的小伙伴给个三…

avue-crud组件的行内编辑实现失焦保存,在没有右侧操作栏的情况下

前言 关于 avue 框架,其实本来不想写一篇随笔记录的,因为目前在网上有很多文章,关于其配置项介绍的比较详细,而且官网上也有对应的文档,这两者结合足以满足大部分的开发需求。 不过,产品经理总会有些不一…

[大二下]什么是NPM

[大二下]什么是npm? 什么是NPM? 最简单来回答: ​ 就是一个包管理器, 一个仓库, 谁需要里面的物品, 谁就拿 npm 全称 Node Package(译: 包,包裹) Manager(译:如下). 直译过来就是 Node的包管理, 但是我们真正咱们约定俗成的称 NPM为"Node的包管理器". npm是Jav…