Dubbo-go 概念

Dubbo-go系列文章(一)

Table of Contents

本文基于Dubbo-go v3.0.0最新架构编写,相比于Dubbo-go v1.5.x更新了大量的新特性,这篇文章将从一个初学者角度来编写,可能还有很多地方因为了解不深入而导致理解偏差,请谅解并欢迎在文章下面指正。

什么是Dubbo-go?

Dubbo-go是一个微服务治理框架,在Dubbo官网上可以看到提供了六大能力(下面仅列出我已经了解的部分):

  • 高性能RPC框架
  • 服务自动注册和发现

RPC

如果你还不了解RPC是什么,请先阅读“谁能用通俗的语言解释一下什么是 RPC 框架?”后在接着往下看。

Provider/Consumer

向外提供具体实现的称之为Provider,与之相对调用具体实现的称之为Consumer。

RPCService

在Dubbo-go中一个RPCService表明一个Provider提供的类(简称为Service,有时也称为Interface-level Service),该类可以供Consumer调用,一般来说,一个RPCService与一个接口名(interface)一一对应,与之相关的接口或结构包括common.RPCService和common.Service。

URL

URL标识Dubbo-go中的一具体实体,其被定义在common.URL结构中,举个例子:

这与HTTP的URL结构非常相似,其中:

  • {Protocol}表示协议名
  • {IP}和{Port}表示IP地址和端口
  • {Path}指路径,一般来说是{Path}是接口名(interface name)
  • 参数: 类似于HTTP的GET请求的键值对参数,可以携带额外的信息

在一个URL表示一个RPCService时,Provider端会根据该URL中指定的端口和参数暴露服务,而Consumer端则会使用根据对应的URL发起远程调用。

服务自动注册和发现

在前面的部分提到过,Consumer端需要通过URL才能调用Provider端的代码,而在Consumer端启动的时候并不知道关于Provider端的信息,包括但不限于Provider端的IP、Port、提供的RPCService信息等等,所以必须有一个第三方结构存放这些信息,在Dubbo-go中称之为Registry。

Registry

Regsitry翻译作注册中心,目前Dubbo-go支持的注册中心包括ZooKeeper简称zketcdNacos等。注册中心其实并没有那么神秘,它存储的内容实际上就是所有Provider端的URLs。

Tips: 以接口级注册模型为例,如果你不知道里面的关系请忽略,此外了解更多关于UserProvider等结构体的定义,请参阅dubbo-go-samples/helloworld

假设Provider端暴露一个RPCService,其对应的URL称为url0,接口名为org.apache.dubbo.UserProvider,那么在zk中的注册模型如下图所示:

url0的实际格式如下所示:

相比于之前介绍过的URL,实际的URL携带有更多的参数,稍微分析一下我们只需要重点关注其中最重要的参数:

  • methods: org.apache.dubbo.UserProvider提供的可以被调用的方法名

这样在Consumer端启动的时候只需要根据需要的接口名去注册中心中获取相应的URLs,就能确定Provider端的IP地址、端口、路径以及可调用的方法名,至此Consumer端才具备了调用远端服务的可能。

接口级/应用级注册模型

所谓接口级注册模型是指在注册中心中以接口为级别进行注册1,在上面的示例中可以很清晰的看到,接口名(org.apache.dubbo.UserProvider)是作为注册标识的,其中更一般的注册结构可以被概括为:

对于Consumer端来说,RPC过程为:希望调用Interface1 -> 从注册中心中找到提供Interface1服务的全部Provider实例 -> 通过负载均衡算法选择一个实例 -> 发起远程调用。

应用级注册模型则是另一个思路,假设Application1提供的服务为Interface1和Interface2,Application2提供的服务为Interface3,那么注册中心注册的结构为:

可以注意到的是注册中心将接口名换成了应用名,那么此时对于Consumer端来说,RPC过程变为了:希望调用Interface1 -> 通过ServiceNameMapping获得提供Interface1服务的应用Application12 -> 从注册中心中找到Application1的信息 -> 获取接口的元数据信息(服务自省) -> 通过负载均衡算法选择一个实例 -> 发起远程调用。(ServiceNameMapping和服务自省会在后续文章中介绍)。

在应用级注册模型中,1个应用对应1个或多个服务。这两种模型之间为了RPC调用做了同样的事情,但是应用级注册模型还更复杂了,其背后的逻辑是3

  • 与业界主流微服务模型对齐,比如 SpringCloud、Kubernetes Native Service等;
  • 提升性能与可伸缩性。注册中心数据的重新组织(减少),能最大幅度的减轻注册中心的存储、推送压力,进而减少 Dubbo Consumer 侧的地址计算压力;集群规模也开始变得可预测、可评估(与 RPC 接口数量无关,只与实例部署规模相关)。
  1. https://thurstonzk2008.com/2020/12/25/dubbo%e7%9a%84%e5%ba%94%e7%94%a8%e7%ba%a7%e6%9c%8d%e5%8a%a1%e5%8f%91%e7%8e%b0/

  2. https://dubbo.apache.org/zh/blog/2021/01/14/dubbo-go%E5%BA%94%E7%94%A8%E7%BB%B4%E5%BA%A6%E6%B3%A8%E5%86%8C%E6%A8%A1%E5%9E%8B/

  3. https://dubbo.apache.org/zh/blog/2021/06/02/dubbo3-%E5%BA%94%E7%94%A8%E7%BA%A7%E6%9C%8D%E5%8A%A1%E5%8F%91%E7%8E%B0/#3-dubbo-%E5%BA%94%E7%94%A8%E7%BA%A7%E6%9C%8D%E5%8A%A1%E5%8F%91%E7%8E%B0%E7%9A%84%E6%84%8F%E4%B9%89