dubbogo 3.0:牵手 gRPC 走向云原生时代

自从 2011 年 Dubbo 开源以后,被大量中小公司采用,一直是国内最受欢迎的 RPC 框架。2014年 因为阿里内部组织架构调整,Dubbo 暂停维护了一段时间,以后随着 Spring Cloud 的面世,两个体系在融合中一块儿助推了微服务的火热。docker

不过这世界变化快,自从以 docker 为表明的的容器技术和以 k8s 为表明的容器编排技术登上舞台以后,云原生时代到来了。在云原生时代,不可变的基础设施给原有的中间件带来的了不可变的中间件基础设施:gRPC 统一了底层通讯层,protobuf 统一了序列化协议,以 envoy + istio 为表明的 service mesh 逐渐统一了服务的控制面与数据面。编程

dubbogo 的自然使命是:Bridging the gap between Java and Go。保持 Go 应用与 Java 应用互联互通的同时,借助 Go 语言(事实上的远程桌面第一云原生语言)的优点拥抱云原生时代。dubbogo 社区 2020 年勠力打造三支箭:已经发布的对齐 dubbo 2.7 的 dubbogo v1.5 版本、近期将要发布的 sidecar 形态的 dubbo-go-proxy 项目 以及 处于进行时的 dubbogo 3.0。网络

用一句话归纳 dubbogo 3.0 便是:新通讯协议、新序列化协议、新应用注册模型以及新的服务治理能力!本文主要着重讨论 dubbogo 3.0 的新通讯协议和应用级服务注册发现模型。架构

  1. dubbogo 3.0 vs gRPC

知己知彼,方能进步。dubbogo 3.0 的通讯层改进主要借鉴了 gRPC。app

简单来讲就是http2协议的基础之上,增长了特定的协议header:“grpc-”开头的header字段,采用特定的打解包工具(protobuf)对数据进行序列化,从而实现RPC调用。
众所周知,gRPC 几乎没有服务治理能力,而阿里云现有 dubbo 框架兼具 RPC 和服务治理能力,总体实力不逊于 gRPC。但“你们都用gRPC” 这样的背景之下,dubbogo 3.0 的新通讯协议就必须完美兼容 gRPC,对开发者已部署的服务彻底兼容,并在此基础之上延续已有 dubbo 协议和服务治理能力,进而推出一系列新策略:好比mesh支持、应用级服务注册等。框架

  1. dubbogo 3.0 vs dubbogo 1.5

目前已有的 dubbo 2.7 协议已经尽量实现了 gRPC 的支持。开发者能够经过 protoc-gen-dubbo 工具将 pb IDL 协议转换为框架支持的 stub,再借助底层 gRPC conn 的 RPC 过程,将已有的服务治理能力自上而下传递给了 gRPC,所以实现了 gRPC 服务的支持。运维

dubbo-go v1.5.x 也支持 gRPC 的 Stream 调用。和 unary RPC 相似,经过产生框架支持的 stub,在底层gRPC stream 调用的基础之上,将流式 RPC 的能力和并入框架。但因为 dubbo v2.7.x / dubbo-go v1.5.x 自己并不支持流式调用,因此没有对 gRPC stream 调用的进行上层服务治理支持。异步

开发者所面临的问题就是:咱们在使用dubbo-go2.7进行grpc协议传输的时候,或多或少不是那么放心。编程语言

而即将推出的 dubbo-go 3.0 协议将从根源解决这个问题。ide

  1. 协议兼容的三种层次

笔者认为,一款服务框架对于第三方协议的支持可分为三个程度:应用层次、协议层次、传输层次。

一款框架若是在一个协议的 sdk 之上封装接口,能够认为它处于应用层次支持,这样的框架须要遵循下层 sdk 的接口,可扩展性较差。

处于协议层次的框架,从配置层到服务治理层均由本框架提供,而在此之下的协议层到网络传输层均使用某个固定的通讯协议,这样的框架能够解决服务治理的问题,但框架自己没法与第三方协议彻底适配,若是不适配就会出现对第三方协议支持的削弱,好比上面说到的 dubbo-go 1.5 对 stream rpc 支持的缺陷。

若是想进一步支持更多的第三方协议,须要从传输层下手,真正了解第三方协议的具体字段、所依赖的底层协议(好比 HTTP2)的帧模型和数据流,再开发出与第三方协议彻底一致的数据交互模块,做为本框架的底层。这样作的好处是最大程度赋予了协议的可扩展性,能够在兼容已有协议的基础之上,可选地增长开发者须要的字段,从而实现已有协议没法实现的功能,就好比 dubbogo 3.0 将支持的反压策略。

  1. 基于 HTTP2 的通讯流程

gRPC 一次基于 HTTP2 的 unary rpc 调用传输主要流程以下:

client 发送 Magic 信息 PRI * HTTP/2.0rnrnSMrnrn

server 收到并检查是否正确

client 和 server 互相发送 setting 帧,收到后发送ACK 确认

client 发送 Header 帧,包含 gRPC 协议字段,以 End Headers 做为 Header 结束标志

client 紧接着发送 Data 帧,包含 RPC 调用的 request 信息,以 End Stream 做为 Data 结束标志

server 调用函数得到结果

server 发送 Header 帧,包含 gRPC 协议字段,以 End Headers 做为 Header 结束标志

server 紧接着发送Data帧,包含 RPC 调用回传的 response 信息

server 紧接着再次发送 Header 帧,包含 RPC 状态和 message 信息,以 End Stream 做为本次 RPC 调用结束标志

另外,在 gRPC 的 stream 调用中,可在 server 端回传的过程当中发送屡次 Data,调用结束后再发送 Header 终止 RPC 过程,并汇报状态信息。

dubbogo 3.0 的通讯层将在 HTTP2 通讯协议之上采用一样的通讯流程,以保证与 gRPC 的底层通讯沟通能力。

  1. dubbogo 3.0 预期通讯架构

除了通讯协议采用 HTTP2 外,dubbogo 3.0 将采用 基于 google protobuf 的 triple 协议【下面称为 dubbo3 协议】做为 dubbogo 3.0 的序列化协议,为 dubbo 未来支持更多的编程语言打下通讯协议层面的基础。 目前设计的 dubbogo 3.0 传输模型

为保证同时支持 unary RPC 和 stream RPC,在 server 端和 client 端增长数据流结构,以异步调用的形式完成数据传递。

继续支持原有的 TCP 通讯能力

在 HTTP2 的通讯协议之上支持 dubbo3协议,decode 过程兼容 gRPC 使用的的 protobuf,保证与 gRPC 服务打通。

  1. 应用级服务注册发现

6.1 应用级服务注册发现介绍

dubbogo 3.0 使用的新一代服务注册发现体系,将摒弃旧版的“接口级注册发现”,使用“应用级别注册发现”。

简单地说,接口级别注册发现,在注册中心中以 RPC 服务为key,以实例列表做为 value 来组织数据的,而咱们新引入的“应用粒度的服务发现”,它以应用名(Application)做为 key,以这个应用部署的一组实例(Instance)列表做为 value。这带来两点不一样:

数据映射关系变了,从 RPC Service -> Instance 变为 Application -> Instance

数据变少了,注册中心没有了 RPC Service 及其相关配置信息

能够认为,基于应用粒度的模型所存储和推送的数据量是和应用、实例数成正比的,只有当咱们的应用数增多或应用的实例数增加时,地址推送压力才会上涨。

而对于基于接口粒度的模型,数据量是和接口数量正相关的,鉴于一个应用一般发布多个接口的现状,其数量级通常是比应用粒度的数十倍。另一个关键点在于,接口的定义更多的是业务侧的内部行为,接口粒度致使的集群规模评估的不透明,而实例、应用增加都一般是在运维侧的规划之中,可控性较好。

工商银行曾经对这两个模型进行生产测算:应用级服务注册模型可让注册中心上的数据量变成原来的 1.68%,新模型可让 zookeeper 轻松至成 10 万级别的服务量和 10 万级别的节点量。

6.2 元数据中心同步机制的引入

数据中心的数据量变少所形成的结果,是RPC 服务相关的数据在注册中心消失了,只有 application - instance 这两个层级的数据。为了保证这部分缺乏的 RPC 服务数据仍然能被 Consumer 端正确的感知,咱们在 Consumer 和 Provider 间创建了一条单独的通讯通道,目前针对元数据同步有两种具体的可选方案,分别是:

内建 MetadataService。

独立的元数据中心,经过中细化的元数据集群协调数据。

相关文章
相关标签/搜索