Skip to content

dubbo go V1.0 design

vito.he edited this page May 29, 2019 · 1 revision

设计思路:

借鉴 dubbo 分层设计,v1.0.x 版本需要实现 dubbo 的主要功能以及实现 dubbo 可扩展点的易扩展性,与dubbo v2.6.x版本对应。尽量较少非必须的功能,以及现阶段难以拆分并对使用无感知(可以后续版本再来拆分而对使用者无感知)的分层。


1.框架设计:

遵循 dubbo 的分层框架设计,但具体每层的实现可能会不一致,可能是由于语言特性的差异,如 proxy 层;也有可能是由于历史版本已经实现功能而非重构必要,如 registry 层。但是每层的主要功能、开放给其他模块的方法不变。 框架设计

2.各层说明:

扩展支持:

目标:可以实现 Java 版本中定义的全部扩展点的扩展性支持,实现代码无侵入扩展。

现状:扩展点扩展需要对接口进行实现,并在引用的项目中的 init 方法中通过 setDefaultXXX 覆盖默认实现。

任务:进一步封装,引入 Java 实现的 extention 概念,实现一个全局单例对象。

config 配置层:

目标:对外配置接口,以 ServiceConfig/ReferenceConfig 为中心,在使用时可以显式初始化配置类,也可以放于 init 方法中隐式初始化。

现状:当前开发分支有 ProviderServiceConfig/ServiceConfig 与之对应,目前的作用只是用来描述一个 service。

任务:需要修改升级作为 consumer 和 provider 端的初始化入口,包含初始化多个 protocol 单例对象和返回 invoker、exporter 对象等过程。

proxy 服务代理层:

目标:服务接口透明代理,生成客户端代理服务(通过 Golang reflect 显式将 consumer service 代理为 ReferenceConfig.refer 返回的 invoker 入门);为用户自定义服务生成服务端代理服务(通过 Golang reflect 调用 privider service 实现方法,包装生成 ServiceInvoker,供 protocol 层 Handler 直接调用)以 ServiceProxy 为中心,可扩展接口为 ProxyFactory。

现状:周子庆提供客户端代理服务的解决思路,服务端代理在 dubbo 和 jsonRPC server 中已经提供。

任务:

①先抽象一个 ProxyFactory 支持可扩展。

②需要将服务端代理抽离。

③新写一个客户端代理服务

registry 注册中心层:

目标:封装每一个服务地址的注册与发现,以服务 URL 为中心,可扩展接口为 Protocol,Registry,Listener,ServiceURL。目前默认实现为zookeeper已经完成。

现状:已经实现,但是目前的 listener 方法为所有 service 共用一个监听,导致上层无法支持一个 service 多个注册中心的需求,需要修改。目前未实现 protocol 接口。

任务:

①修改 listener 实现为每个 service 一个监听,并实现一个 service 多个注册中心的配置。

②实现 RegistryDirectory,作为客户端 serviceURL 缓存,传入到 clusterInvoker/protocolInvoker。

③实现 protocol 接口,为 config 层提供调用入口。

④ protocol refer 方法,生成 service 对应的 clusterInvoker/protocolInvoker。

⑤ protocol export 方法,生成 service 对应的 protocolExporter。

cluster 路由层:

目标:封装多个提供者的路由及负载均衡,并桥接注册中心,以 Invoker 为中心,可扩展接口为 Cluster, Directory, Router, LoadBalance。

现状:clusterInvoker 有一个简单实现。

任务:

①实现 RegistryDirectory 的路由策略,以及可扩展支持。

②抽象 clusterInvoker,实现 failover/failfast 等 Java 已有扩展实现。

③抽象客户端负载均衡,实现 round_robin/random 等 Java 已有扩展实现。

monitor 监控层:1.0版本暂不计划实现(需要讨论确认)

protocol 远程调用层:

目标:封装 RPC 调用,以 Invocation/Result 为中心,可扩展接口为 Protocol/Invoker/Exporter

现状:jsonRPC/dubbo 分别有 client和 server 的实现,RPC 调用(invoker)、连接\传输(transport)、序列化(serialize)层未抽象。

任务:

①将 protocol 的 RPC 调用层抽象出来,提供 refer/exporter 方法导出 dubbo/httpInvoker 以及 dubbo/httpExporter。

②实现 dubbo/httpExporter 的 Handler 逻辑。

③支持调用端/服务端 invoke filter,抽象 filter 接口、实现 Java 现有实现。

  • Go 的 dubbo 协议基于 getty 将以下三层已经全部封装。暂时不建议拆。
  • exchange 信息交换层:1.0版本暂不计划实现(需要讨论确认)http 实现的 json 协议因为基于 Go http/net 实现,所以只能暂时不支持异步调用。
  • transport 网络传输层:1.0 版本暂不计划实现(需要讨论确认)
  • serialize 数据序列化层:1.0 版本暂不计划实现(需要讨论确认)

3.关系说明:

在 RPC 中,Protocol 是核心层,也就是只要有 Protocol + Invoker + Exporter 就可以完成非透明的 RPC 调用,然后在 Invoker 的主过程上 Filter 拦截点。

图中的 Consumer 和 Provider 是抽象概念,只是想让看图者更直观的了解哪些类分属于客户端与服务器端,不用 Client 和 Server 的原因是 Dubbo 在很多场景下都使用 Provider, Consumer, Registry 划分逻辑拓普节点,保持统一概念。

而 Cluster 是外围概念,所以 Cluster 的目的是将多个 Invoker 伪装成一个 Invoker,这样其它人只要关注 Protocol 层 Invoker 即可,加上 Cluster 或者去掉 Cluster 对其它层都不会造成影响,因为只有一个提供者时,是不需要 Cluster 的。

Proxy 层封装了所有接口的透明化代理,而在其它层都以 Invoker 为中心,只有到了暴露给用户使用时,才用 Proxy 将 Invoker 转成接口,或将接口实现转成 Invoker,也就是去掉 Proxy 层 RPC 是可以 Run 的,只是不那么透明,不那么看起来像调本地服务一样调远程服务。

Registry 和 Monitor 实际上不算一层,而是一个独立的节点,只是为了全局概览,用层的方式画在一起。

4.模块分包(待讨论)

参考资料