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

目录
  • 背景
  • 概述
  • 架构
    • 设计理念
    • 面向接口设计
    • 会话 Session
    • 消息 Message
    • 协议 Proto
    • 编码 Codec
    • 连接 Socket
    • 有机的组合
    • 插件 Plugin
    • 组件
  • 未来展望

背景

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

开源不易,需要更多小伙伴加入,共创 DMicro. 如果你希望使用 DMicro, 赶快引入代码,搭建你的第一个新项目吧!如果你也想为 DMicro 生态添砖加瓦,赶快 Fork 代码,给我们提交 pr 吧!

以上就是Go 微服务开发框架DMicro设计思路详解的详细内容,更多关于Go 微服务开发框架DMicro的资料请关注我们其它相关文章!

(0)

相关推荐

  • go zero微服务实战性能优化极致秒杀

    目录 引言 批量数据聚合 降低消息的消费延迟 怎么保证不会超卖 结束语 引言 上一篇文章中引入了消息队列对秒杀流量做削峰的处理,我们使用的是Kafka,看起来似乎工作的不错,但其实还是有很多隐患存在,如果这些隐患不优化处理掉,那么秒杀抢购活动开始后可能会出现消息堆积.消费延迟.数据不一致.甚至服务崩溃等问题,那么后果可想而知.本篇文章我们就一起来把这些隐患解决掉. 批量数据聚合 在SeckillOrder这个方法中,每来一次秒杀抢购请求都往往Kafka中发送一条消息.假如这个时候有一千万的用户同

  • golang微服务框架基础Gin基本路由使用详解

    目录 概述 1. 基本路由 2. 路由参数 获取URL路径全部参数 获取URL路径单个参数 获取URL中指定的参数 获取指定默认值的参数的 概述 路由是自定义url地址执行指定的函数,良好的路由定义可以对seo起到很好的效果. 1. 基本路由 gin框架封装了http库,提供了 GET.POST.PUT.DELETE.PATCH.HEAD.OPTIONS 这些http请求方式. 使用 router.method() 来绑定路由 func (group *RouterGroup) METHOD(r

  • Go微服务项目配置文件的定义和读取示例详解

    目录 前言 场景 定义配置 配置文件 加载配置文件 实现原理 总结 项目地址 前言 我们在写应用时,基本都会用到配置文件,从各种 shell 到 nginx 等,都有自己的配置文件.虽然这没有太多难度,但是配置项一般相对比较繁杂,解析.校验也会比较麻烦.本文就给大家讲讲我们是怎么简化配置文件的定义和解析的. 场景 如果我们要写一个 Restful API 的服务,配置项大概有如下内容: Host,侦听的 IP,如果不填,默认用 0.0.0.0 Port,侦听的端口,必填,只能是数字,大于等于80

  • Go chassis云原生微服务开发框架应用编程实战

    目录 什么是Go chassis 文章目标 诞生背景 如何快速开发一个微服务 统一治理和协议模型 可扩展的处理链条:handler chain as middleware 不只是API,通过配置简化开发过程 插件化 什么是Go chassis go chassis是一个go语言微服务开发框架,专注于云原生应用的开发主要的使用场景是云服务开发.go chassis将云服务开发过程中沉淀的能力融入到了开发框架中,以帮助开发团队快速编写云原生应用. 文章目标 本文介绍我们的设计理念和目标,为何go c

  • 微服务效率工具 goctl 深度解析

    目录 前言 goctl 的由来 1. goctl 的诞生 2. 为什么需要 goctl? 3. 怎么理解开发规范? 4. 怎么理解工程效率? 二 .goctl 的安装及功能介绍 1. 介绍 2. 安装 go get/install docker 3. 功能介绍 goctl completion 1.3.5 1.3.6 goctl migrate goctl env 1. 环境查看 2. 修改参数 3. 依赖检测/安装 goctl rpc 4. 编辑器插件 三.goctl 使用中遇到的问题 1.

  • go zero微服务框架logx日志组件剖析

    目录 addTenant api 和 rpc 的实现 logx 日志组件剖析 Go-zero 中 logx 是如何使用的? Logx 基本的数据结构 Logx 的默认接口实现 Logx 自定义存储日志位置 和 实现自定义接口的方式 自定义存储日志位置 实现自定义接口 addTenant api 和 rpc 的实现 上一篇我们说到咱们还剩下 addTenant 功能还未实现,不知道有没有兄弟感兴趣去实验一波的,本篇文章进行简要补充 根据上一篇文章分析,其实我们只需要执行如下几步即可: 编写 ten

  • Go 微服务开发框架DMicro设计思路详解

    目录 背景 概述 架构 设计理念 面向接口设计 会话 Session 消息 Message 协议 Proto 编码 Codec 连接 Socket 有机的组合 插件 Plugin 组件 未来展望 背景 DMicro 诞生的背景,是因为我写了 10 来年的 PHP,想在公司内部推广 Go, 公司内部的组件及 rpc 协议都是基于 swoole 定制化开发的.调研了市面上的各种框架,包括 beego,goframe,gin,go-micro,go-zero,erpc 等等,可能是我当时技术能力有限,

  • SpringCloud搭建netflix-eureka微服务集群的过程详解

    1.打开官网稍微学习一下,了解一下spring cloud是个什么东西,大概有哪些组件等 https://spring.io/projects/spring-cloud https://docs.spring.io/spring-cloud-netflix/docs/current/reference/html/ 2.新建项目 打开网址:https://start.spring.io/ 选择需要引入的组件,然后下载下来即可 3.更改项目结构 为了测试的方便,需将项目结构更改为多模块的项目. 步骤

  • Rainbond对微服务进行请求速率限制详解

    目录 前置条件 操作流程 常见问题 Rainbond 默认支持基于 envoy 的全局速率限制.在 Rainbond 默认提供的综合网络治理插件中呈现.本文我们将一个用例呈现 Rainbond 中全局速率限制的使用方式. 前置条件 Rainbond平台已部署完成. 在Rainbond中部署可访问的 Demo 业务. 为此组件开通综合网络治理插件. 参考视频 https://player.bilibili.com/player.html?aid=540728010 Rainbond 速率限制设置参

  • 微服务和分布式的区别详解

    分布式架构是分布式计算技术的应用和工具,目前成熟的技术包括J2EE, CORBA和.NET(DCOM),这些技术牵扯的内容非常广,相关的书籍也非常多,也没有涉及这些技术的细节,只是从各种分布式系统平台产生的背景和在软件开发中应用的情况来探讨它们的主要异同. 微服务架构是一项在云中部署应用和服务的新技术.大部分围绕微服务的争论都集中在容器或其他技术是否能很好的实施微服务,而红帽说API应该是重点. 微服务可以在"自己的程序"中运行,并通过"轻量级设备与HTTP型API进行沟通&

  • 使用Spring Boot+gRPC构建微服务并部署的案例详解

    目录 1.  为什么要用Istio? 1.1.  为什么要使用gRPC作为通信框架? 1.2. 编写业务代码 1.3、 编写Dockerfile 2. 编写部署文件 3. 部署应用到Istio 大家好,搞微服务也有好几年时间,从16年开始就一直关注微服务,到现在一直在使用的还是SpringCloud原生那套,虽然后来出现了SpringCloud Alibaba,但由于前面的所有系统框架都已定,就没有在变化,而在微服务的实施过程,为了降运维的服务度,先后使用了jenkins,docker, kub

  • SpringCloud微服务应用config配置中心详解

    目录 前言 一.传统应用配置痛点 二.Config 配置中心介绍 三.服务端Config Server搭建 1.pom依赖 2.application启动类配置 3.application.yml配置 4.test-dev.xml(客户端应读取的配置) 5.项目结构 四.客户端Config Client搭建 1.pom依赖 2.application启动类配置 3.bootstrap.yml配置 4.application.yml配置 5.测试controller 6.项目结构 五.动态刷新 六

  • go-micro微服务domain层开发示例详解

    目录 一 domain层介绍说明 二 model层开发 三 repository层开发 四 service层开发 最后 一 domain层介绍说明 domain层专注于数据库数据领域开发,我们把数据库相关操作全部写在domain层. model层:数据表字段定义与开发 repository层:数据库数据CURD操作 service层:数据库相关业务操作 对于复杂的业务操作,这样可以使业务逻辑更加清晰,有利于后期开发与维护. 二 model层开发 在model目录下新建 user.go 文件 pa

  • 详解Go语言微服务开发框架之Go chassis

    引言 https://github.com/go-chassis/go-chassis是一个微服务开发框架,而微服务开发框架带来的其中一个课题就是:当单体应用向微服务转型后,有大量的配置需要管理,而你并不希望登录到远端机器去更改配置,并重启应用,尤其是现在已经是容器的时代了,也不希望因为一个配置的变更,而发布一个新的软件包.那么分布式系统中每个进程的动态配置管理及运行时热加载就成为了一个亟待解决的问题.https://github.com/go-chassis/go-archaius为gocha

  • 微服务架构之服务注册与发现功能详解

    目录 微服务的注册与发现 1.服务注册 2.服务发现 3.注册中心 4.现下的主流注册中心 4.1 Eureka 4.1.1 介绍 4.1.2 整体架构 4.1.3 接入Spring Cloud 4.2 ZooKeeper 4.2.1 介绍 4.2.2 整体架构 4.2.3 接入Dubbo生态 4.3 Consul 4.3.1 介绍 4.3.2 整体架构 4.3.3 生态对接 4.4 总结对比 详解微服务架构及其演进史 微服务全景架构全面瓦解 微服务架构拆分策略详解 微服务的注册与发现 我们前面

随机推荐