当前位置: 首页 > news >正文

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

相关文章:

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&#xff…...

[ 常用工具篇 ] CobaltStrike(CS神器)基础(一) -- 安装及设置监听器详解

🍬 博主介绍 👨‍🎓 博主介绍:大家好,我是 _PowerShell ,很高兴认识大家~ ✨主攻领域:【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 🎉点赞➕评论➕收藏 养成习…...

Redis集群

Redis集群 本章是基于CentOS7下的Redis集群教程,包括: 单机安装RedisRedis主从Redis分片集群 1.单机安装Redis 首先需要安装Redis所需要的依赖: yum install -y gcc tcl然后将课前资料提供的Redis安装包上传到虚拟机的任意目录&#xff…...

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实现读取表中的数据&#xff0c;生成excel文件 1.简介 本次使用java代码整合kettle9.3版本&#xff0c;数据库使用mysql。 2.jar包导入 项目需要依赖部分kettle中的jar包&#xff0c;请将这部分jar包自行导入maven仓库。 <dependency><groupId…...

分享微信点餐小程序搭建步骤_微信点餐功能怎么做

线下餐饮实体店都开始摸索发展网上订餐服务。最多人选择的是入驻外卖平台&#xff0c;但抽成高&#xff0c;推广还要另买流量等问题&#xff0c;也让不少商家入不敷出。在这种情况下&#xff0c;建立自己的微信订餐小程序&#xff0c;做自己的私域流量是另一种捷径。那么&#…...

4、数组、切片、map、channel

目录一、数组二、切片三、map四、channel五、引用类型一、数组 数组&#xff1a; 数组是块连续的内存空间&#xff0c;在声明的时候必须指定长度&#xff0c;且长度不能改变所以数组在声明的时候就可以把内存空间分配好&#xff0c;并赋上默认值&#xff0c;即完成了初始化数组…...

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个简历模板网站&#xff0c;免费下载&#xff0c;建议收藏&#xff01; 2023用最漂亮的简历模板&#xff0c;让面试官眼前一亮。 1、菜鸟图库 个人简历模板|WORD文档模板免费下载 - 菜鸟图库 菜鸟图库除了有超多设计类素材之外&#xff0c;还有很多办公类素材&#…...

【CSS】元素居中总结-水平居中、垂直居中、水平垂直居中

【CSS】元素居中一、 水平居中1.行内元素水平居中&#xff08;1&#xff09;text-align2.块级元素水平居中2.1 margin&#xff08;1&#xff09;margin2.2布局&#xff08;1&#xff09;flex justify-content&#xff08;推荐&#xff09;&#xff08;2&#xff09; flexmargin…...

spring实现AOP

文章目录前言一、AOP的底层实现原理二、AOP的两种开发模式1.使用xml配置文件1.1 添加AOP依赖1.2 创建UserService1.3创建UserServiceImpl1.4创建通知类1.5 创建applicationContext.xml&#xff08;添加aop约束&#xff09;1.6 测试2.使用注解开发2.1 创建bean.xml文件配置注解方…...

neovim搭建cpp环境

文章目录Windowns下NeoVim搭建cpp环境NeoVim安装插件vim-plugindentLinevim-airlinectagstagbarcoc.vimWindowns下NeoVim搭建cpp环境 在开发过程中习惯在DIE环境中使用vim作为编辑器&#xff0c;在单独的编辑器也常使用gvim图形化编辑器。最近看到NeoVim的特性及兼容性方面不输…...

SpringBoot AES加密 PKCS7Padding 模式

AES 简介&#xff1a;DES 全称为Data Encryption Standard&#xff0c;即数据加密标准&#xff0c;是一种使用密钥加密的块算法&#xff0c;1977年被美国联邦政府的国家标准局确定为联邦资料处理标准&#xff08;FIPS&#xff09; AES 密码学中的高级加密标准&#xff08;Advan…...

按键输入驱动

目录 一、硬件原理 二、添加设备树 1、创建pinctrl 2、创建节点 3、检查 编译复制 三、修改工程模板​编辑 四、驱动编写 1、添加keyio函数 2、添加调用 3、驱动出口函数添加释放 4、添加原子操作 5、添加两个宏定义 6、初始化原始变量 7、打开操作 8、读操作 总体代…...

2023年第七周总周结 | 开学倒数第三周

为什么要做周总结&#xff1f; 1.避免跳相似的坑 2.客观了解上周学习进度并反思&#xff0c;制定可完成的下周规划 一、上周问题解决情况 晚上熬夜导致第二天学习状态不好 这周熬夜一天&#xff0c;晚上帮亲戚修手机到22:30&#xff0c;可能是晚上自己的事什么都没做&#xff…...

Springboot扫描注解类

Springboot扫描注解类的入口在AbstractApplicationContext的refresh中&#xff0c;对启动步骤不太了解的&#xff0c;可参考https://blog.csdn.net/leadseczgw01/article/details/128930925BeanDefinitionRegistryPostProcessor接口有多个实现类&#xff0c;扫描Controller、Se…...

猎头网站怎么做/seo是什么专业的课程

sqlSession.selectList("xxx",null,rowBounds);转载于:https://www.cnblogs.com/orziii/p/7406449.html...

linux主机上wordpress的url伪静态化优化技巧/seo电商运营是什么意思

无代码开发是⼀种通过可视化进行应用程序开发的方法&#xff0c;让不同经验水平的人员&#xff0c;都可以通过可视化的用户界面&#xff0c;自定义配置各种管理应用模型&#xff0c;减少企业IT人员编写代码的时间和工作时间&#xff0c;节省成本&#xff0c;来帮助企业快速开发…...

厦门app网站设计/深圳全网信息流推广公司

标签&#xff1a; 二维码 页面重定向 vue 移动端 混合开发 总结 本质&#xff1a;手机app扫码本质是访问二维码携带对应链接。部分app对相关二维码可以定制一定的规范&#xff0c;比如用丰*App扫定制二维码&#xff0c;会打开对应微服务&#xff08;H5&#xff09;指定页面url中…...

广西建设网站/长沙疫情最新情况

一&#xff1a;* 的作用&#xff0c;个人理解代表所有 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的时候三个元素&#xff0c;而l2有4个元素所以出错 二&…...

临沂企业建站效果好/云优化软件

目前最新版本zlib是zlib1.2.8&#xff0c; 安装开始&#xff1b; 方法一&#xff1a; $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方法二&#xff1a; 直接将 URL &#xff1a; http://ww…...

建网站需要哪些语言/没经验怎么开广告公司

什么是TomcatTomcat简单的说就是一个运行JAVA的网络服务器&#xff0c;底层是Socket的一个程序&#xff0c;它也是JSP和Serlvet的一个容器。为什么我们需要用到Tomcat如果你学过html&#xff0c;css&#xff0c;你会知道你写的页面只能自己访问&#xff0c;别人不能远程访问你写…...