自从 2011 年 Dubbo 开源之后,被大量中小公司采纳,始终是国内最受欢迎的 RPC 框架。2014 年 因为阿里外部组织架构调整,Dubbo 暂停保护了一段时间,之后随着 Spring Cloud 的面世,两个体系在交融中一起助推了微服务的炽热。
不过这世界变动快,自从以 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 的新通信协议和利用级服务注册发现模型。
- dubbogo 3.0 vs gRPC
知己知彼,方能提高。dubbogo 3.0 的通信层改良次要借鉴了 gRPC。
简略来说就是 http2 协定的根底之上,减少了特定的协定 header:“grpc-”结尾的 header 字段,采纳特定的打解包工具(protobuf)对数据进行序列化,从而实现 RPC 调用。
家喻户晓,gRPC 简直没有服务治理能力,而阿里云现有 dubbo 框架兼具 RPC 和服务治理能力,整体实力不逊于 gRPC。但“大家都用 gRPC”这样的背景之下,dubbogo 3.0 的新通信协议就必须完满兼容 gRPC,对开发者已部署的服务齐全兼容,并在此基础之上连续已有 dubbo 协定和服务治理能力,进而推出一系列新策略:比方 mesh 反对、利用级服务注册等。
- 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 协定将从本源解决这个问题。
- 协定兼容的三种档次
笔者认为,一款服务框架对于第三方协定的反对可分为三个水平:利用档次、协定档次、传输档次。
一款框架如果在一个协定的 sdk 之上封装接口,能够认为它处于利用档次反对,这样的框架须要遵循上层 sdk 的接口,可扩展性较差。
处于协定档次的框架,从配置层到服务治理层均由本框架提供,而在此之下的协定层到网络传输层均应用某个固定的通信协议,这样的框架能够解决服务治理的问题,但框架自身无奈与第三方协定齐全适配,如果不适配就会呈现对第三方协定反对的减弱,比方下面说到的 dubbo-go 1.5 对 stream rpc 反对的缺点。
如果想进一步反对更多的第三方协定,须要从传输层下手,真正理解第三方协定的具体字段、所依赖的底层协定(比方 HTTP2)的帧模型和数据流,再开发出与第三方协定完全一致的数据交互模块,作为本框架的底层。这样做的益处是最大水平赋予了协定的可扩展性,能够在兼容已有协定的根底之上,可选地减少开发者须要的字段,从而实现已有协定无奈实现的性能,就比方 dubbogo 3.0 将反对的反压策略。
- 基于 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 的底层通信沟通能力。
- 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 服务买通。
- 利用级服务注册发现
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。
独立的元数据中心,通过中细化的元数据集群协调数据。