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) errorUnpack(Message) error
}
Version()
返回该协议的 id 和名字,两个组成唯一的版本号.Pack
对消息Message
对象进行序列化.Unpack
对字节流反序列化,生成一个消息Message
对象.
目前框架已支持 Http
,Json
,Raw
,Protobuf
,JsonRpc
这 5 个协议.
RAW
协议组成如下:
其他协议可以参考代码.
编码 Codec
作为一个通用性的框架,支持的协议可以有多种,消息体的编解码也可以有多少种. drpc
使用 Codec
接口对消息体 Body 进行编解码.
接口的定义如下:
type Codec interface {ID() byteName() stringMarshal(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 V6
Unix Socket
KCP
QUIC
支持对连接的性能调优.
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
能在大家的呵护及鞭策下茁长成长.
相关文章:
Go 微服务开发框架 DMicro 的设计思路
Go 微服务开发框架 DMicro 的设计思路 DMicro 源码地址: Gitee:dmicro: dmicro是一个高效、可扩展且简单易用的微服务框架。包含drpc,dserver等 背景 DMicro 诞生的背景,是因为我写了 10 来年的 PHP,想在公司内部推广 Go, 公司内部的组件及 rpc 协议都…...
浅谈功能测试
1.功能测试流程 1.1 功能测试流程 # 功能测试大致按照以下流程进行: (1).需求分析与评审(2).测试计划与测试方案(3).测试用例设计(4).测试用例评审(5).执行用例(6).缺陷跟踪及报告产出 1.2 功能测试流程详解 (1).需求分析与评审 功能测试应从需求出发, 功能测试就是尽量覆…...
UDP的详细解析
UDP的详细解析 文章目录UDP的详细解析UDP 概述UDP的首部格式检验和的计算抓包测试参考TCP/IP运输层的两个主要协议都是互联网的正式标准,即:用户数据报协议UDP (User Datagram Protocol)传输控制协议TCP (Transmission Control Protocol) 按照OSI的术语…...
史上最详细JUC教程之Synchronized与锁升级详解
在Java早期版本中,synchronized属于重量级锁,效率低下,因为监视器锁(monitor)是依赖于底层的操作系统的Mutex Lock来实现的,挂起线程和恢复线程都需要转入内核态去完成,阻塞或唤醒一个Java线程需…...
Vue|初识Vue
Vue是一款用于构建用户界面的JavaScript框架。它基于标准HTML、CSS和JavaScript构建,并提供了一套声明式的、组件化的编程模型,帮助开发者高效地开发用户界面。 初识Vue1. Vue简介2. 开发准备3. 模板语法3.1 差值语法3.2 指令语法4. 数据绑定4.1 单向数据…...
在职阿里6年,一个29岁女软件测试工程师的心声
简单的先说一下,坐标杭州,14届本科毕业,算上年前在阿里巴巴的面试,一共有面试了有6家公司(因为不想请假,因此只是每个晚上去其他公司面试,所以面试的公司比较少)其中成功的有4家&…...
(C语言)自定义类型,枚举与联合
问:1. 结构体在自引用的时候不能怎么样?可以怎么样?2. Solve the problems:自定义一个学生结构体类型,要包含姓名,性别,年龄,六科成绩,家乡(也为结构体&#…...
node.js服务端笔记文档学会写接口,学习分类:path、包、模块化、fs、express、中间件、jwt、开发模式、cors。
node.js 学习笔记 node.js服务端笔记文档学会写接口,path、包、模块化、fs、express、中间件、JWT、开发模式、cors。 gitee:代码接口笔记 1什么是node.js nodejs 是基于ChromeV8,引擎的一个javaScript 运行环境。node.js 无法使用DOM和BO…...
初始C++(三):引用
文章目录一.引用的概念二.引用的使用1.引用作为输出型参数2. 引用作为函数返回值3.const引用三.引用的一些小问题四.引用和指针五.引用和指针的区别一.引用的概念 引用的作用是给一个已经存在的变量取别名,编译器不会为引用变量开空间,引用变量和被他引…...
【前端】参考C站动态发红包界面,高度还原布局和交互
最近有些小伙伴咨询博主说前端布局好难,其实都是熟能生巧! 模仿C站动态发红包界面,cssdiv实现布局,纯javascript实现交互效果 目录 1、界面效果 2、界面分析 2.1、整体结构 2.2、标题 2.3、表单 2.4、按钮 3、代码实现 3.…...
VR全景带你浪漫“狂飙”情人节,见证甜蜜心动
当情人节遇上VR,足以让情侣过一个难忘的情人节。马上情人节就要到了,大家是不是还在绞尽脑汁的想着,如何和另一半过一个浪漫的情人节呢?老套的剧情已经不能吸引人了,让我们看看VR全景给情人节带来了哪些不同的体验吧&a…...
Linux系统安全之iptables防火墙
目录 一.iptables防火墙基本介绍 二.iptables的四表五链 三.iptables的配置 1.iptables的安装 2.iptables防火墙的配置方法 四.添加、查看、删除规则 1.查看(fliter)表中的所有链 iptables -L 2.使用数字形式(fliter)表所有链 查看输出结果 iptables -nL 3.清空表中所…...
【C#基础】C# 变量与常量的使用
序号系列文章1【C#基础】C# 程序通用结构2【C#基础】C# 基础语法解析3【C#基础】C# 数据类型总结文章目录前言一. 变量(variable)1,变量定义及初始化2,变量的类别3,接收输出变量二. 常量(constantÿ…...
[ 常用工具篇 ] CobaltStrike(CS神器)基础(一) -- 安装及设置监听器详解
🍬 博主介绍 👨🎓 博主介绍:大家好,我是 _PowerShell ,很高兴认识大家~ ✨主攻领域:【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 🎉点赞➕评论➕收藏 养成习…...
Redis集群
Redis集群 本章是基于CentOS7下的Redis集群教程,包括: 单机安装RedisRedis主从Redis分片集群 1.单机安装Redis 首先需要安装Redis所需要的依赖: yum install -y gcc tcl然后将课前资料提供的Redis安装包上传到虚拟机的任意目录ÿ…...
00---C++入门
1. C关键字(C98) C总计63个关键字,C语言32个关键字 2. 命名空间 在C/C中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进…...
Spring-事务2
文章目录前言一、事务的特性(ACID)二、事务的隔离级别三、spring中的事务平台事务管理器.事务定义ISOLation_XXX:**事务隔离级别.**PROPAGATION_XXX:**事务的传播行为**.事务状态关系:四、使用XML文件配置事务1、 搭建…...
Windows Git Bash 配置
Windows Git Bash 配置 本文参考的文章: 在 Windows 的 Git Bash 中使用包管理器 - iris (ginshio.org)Git bash 安装 pacman & Windows 解压 zst 文件 | 伪斜杠青年 (lckiss.com) 一、Git的安装 Git 的安装应该是都会的,但还是应该说以下&#…...
java代码整合kettle9.3实现读取表中的数据,生成excel文件
java代码整合kettle9.3实现读取表中的数据,生成excel文件 1.简介 本次使用java代码整合kettle9.3版本,数据库使用mysql。 2.jar包导入 项目需要依赖部分kettle中的jar包,请将这部分jar包自行导入maven仓库。 <dependency><groupId…...
分享微信点餐小程序搭建步骤_微信点餐功能怎么做
线下餐饮实体店都开始摸索发展网上订餐服务。最多人选择的是入驻外卖平台,但抽成高,推广还要另买流量等问题,也让不少商家入不敷出。在这种情况下,建立自己的微信订餐小程序,做自己的私域流量是另一种捷径。那么&#…...
4、数组、切片、map、channel
目录一、数组二、切片三、map四、channel五、引用类型一、数组 数组: 数组是块连续的内存空间,在声明的时候必须指定长度,且长度不能改变所以数组在声明的时候就可以把内存空间分配好,并赋上默认值,即完成了初始化数组…...
270 uuid
270 uuid 用途 For the creation of RFC4122 UUIDs 可靠性 10000 星星 适应于浏览器或者服务器 官网链接 https://www.npmjs.com/package/uuid https://github.com/uuidjs/uuid 基本使用 import { v4 as uuidv4 } from uuid; uuidv4(); // ⇨ 9b1deb4d-3b7d-4bad-9bdd-2b0d7b3d…...
2023最新简历模板免费下载
下面分享5个简历模板网站,免费下载,建议收藏! 2023用最漂亮的简历模板,让面试官眼前一亮。 1、菜鸟图库 个人简历模板|WORD文档模板免费下载 - 菜鸟图库 菜鸟图库除了有超多设计类素材之外,还有很多办公类素材&#…...
【CSS】元素居中总结-水平居中、垂直居中、水平垂直居中
【CSS】元素居中一、 水平居中1.行内元素水平居中(1)text-align2.块级元素水平居中2.1 margin(1)margin2.2布局(1)flex justify-content(推荐)(2) flexmargin…...
spring实现AOP
文章目录前言一、AOP的底层实现原理二、AOP的两种开发模式1.使用xml配置文件1.1 添加AOP依赖1.2 创建UserService1.3创建UserServiceImpl1.4创建通知类1.5 创建applicationContext.xml(添加aop约束)1.6 测试2.使用注解开发2.1 创建bean.xml文件配置注解方…...
neovim搭建cpp环境
文章目录Windowns下NeoVim搭建cpp环境NeoVim安装插件vim-plugindentLinevim-airlinectagstagbarcoc.vimWindowns下NeoVim搭建cpp环境 在开发过程中习惯在DIE环境中使用vim作为编辑器,在单独的编辑器也常使用gvim图形化编辑器。最近看到NeoVim的特性及兼容性方面不输…...
SpringBoot AES加密 PKCS7Padding 模式
AES 简介:DES 全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1977年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS) AES 密码学中的高级加密标准(Advan…...
按键输入驱动
目录 一、硬件原理 二、添加设备树 1、创建pinctrl 2、创建节点 3、检查 编译复制 三、修改工程模板编辑 四、驱动编写 1、添加keyio函数 2、添加调用 3、驱动出口函数添加释放 4、添加原子操作 5、添加两个宏定义 6、初始化原始变量 7、打开操作 8、读操作 总体代…...
2023年第七周总周结 | 开学倒数第三周
为什么要做周总结? 1.避免跳相似的坑 2.客观了解上周学习进度并反思,制定可完成的下周规划 一、上周问题解决情况 晚上熬夜导致第二天学习状态不好 这周熬夜一天,晚上帮亲戚修手机到22:30,可能是晚上自己的事什么都没做ÿ…...
Springboot扫描注解类
Springboot扫描注解类的入口在AbstractApplicationContext的refresh中,对启动步骤不太了解的,可参考https://blog.csdn.net/leadseczgw01/article/details/128930925BeanDefinitionRegistryPostProcessor接口有多个实现类,扫描Controller、Se…...
猎头网站怎么做/seo是什么专业的课程
sqlSession.selectList("xxx",null,rowBounds);转载于:https://www.cnblogs.com/orziii/p/7406449.html...
linux主机上wordpress的url伪静态化优化技巧/seo电商运营是什么意思
无代码开发是⼀种通过可视化进行应用程序开发的方法,让不同经验水平的人员,都可以通过可视化的用户界面,自定义配置各种管理应用模型,减少企业IT人员编写代码的时间和工作时间,节省成本,来帮助企业快速开发…...
厦门app网站设计/深圳全网信息流推广公司
标签: 二维码 页面重定向 vue 移动端 混合开发 总结 本质:手机app扫码本质是访问二维码携带对应链接。部分app对相关二维码可以定制一定的规范,比如用丰*App扫定制二维码,会打开对应微服务(H5)指定页面url中…...
广西建设网站/长沙疫情最新情况
一:* 的作用,个人理解代表所有 def fun(a,b,c): print(a,b,c) l1[1,2,3] l2[1,2,3,4] fun(*l1) ---->>> 1 2 3 #可以调用打印出所有元素 fun(*l2) ---->>> 出错,需要注意定义fun的时候三个元素,而l2有4个元素所以出错 二&…...
临沂企业建站效果好/云优化软件
目前最新版本zlib是zlib1.2.8, 安装开始; 方法一: $wget http://www.zlib.net/zlib-1.2.8.tar.gz$tar -xvzf zlib-1.2.8.tar.gz$cd zlib-1.2.8.tar.gz$./configure$make$make install方法二: 直接将 URL : http://ww…...
建网站需要哪些语言/没经验怎么开广告公司
什么是TomcatTomcat简单的说就是一个运行JAVA的网络服务器,底层是Socket的一个程序,它也是JSP和Serlvet的一个容器。为什么我们需要用到Tomcat如果你学过html,css,你会知道你写的页面只能自己访问,别人不能远程访问你写…...