自 2017 年 7 月阿里重启 Dubbo 开源,到目前为止 github star 数,contributor 数都有了非常大的提升。2018 年 2 月 9 日阿里决定将 Dubbo 项目贡献给 Apache,经过一周的投票,顺利成为了 Apache 的孵化项目,也就是大家现在看到的 Incubator Dubbo。预计在 2019 年 4 月,Dubbo 可以达成毕业,成为 Apache 的顶级项目。

分支介绍

Dubbo 目前有如图所示的 5 个分支,其中 2.7.1-release 只是一个临时分支,忽略不计,对其他 4 个分支进行介绍。

  • 2.5.x 近期已经通过投票,Dubbo 社区即将停止对其的维护。
  • 2.6.x 为长期支持的版本,也是 Dubbo 贡献给 Apache 之前的版本,其包名前缀为:com.alibaba,JDK 版本对应 1.6。
  • 3.x-dev 是前瞻性的版本,对 Dubbo 进行一些高级特性的补充,如支持 rx 特性。
  • master 为长期支持的版本,版本号为 2.7.x,也是 Dubbo 贡献给 Apache 的开发版本,其包名前缀为:org.apache,JDK 版本对应 1.8。

如果想要研究 Dubbo 的源码,建议直接浏览 master 分支。

Dubbo 2.7 新特性

Dubbo 2.7.x 作为 Apache 的孵化版本,除了代码优化之外,还新增了许多重磅的新特性,本文将会介绍其中最典型的三个新特性:

  • 异步化改造
  • 三大中心改造
  • 服务治理增强

异步化改造

几种调用方式

在远程方法调用中,大致可以分为这 4 种调用方式。oneway 指的是客户端发送消息后,不需要接受响应。对于那些不关心服务端响应的请求,比较适合使用 oneway 通信。

注意,void hello() 方法在远程方法调用中,不属于 oneway 调用,虽然 void 方法表达了不关心返回值的语义,但在 RPC 层面,仍然需要做通信层的响应。

sync 是最常用的通信方式,也是默认的通信方法。

future 和 callback 都属于异步调用的范畴,他们的区别是:在接收响应时,future.get() 会导致线程的阻塞;callback 通常会设置一个回调线程,当接收到响应时,自动执行,不会对当前线程造成阻塞。

Dubbo 2.6 异步化

异步化的优势在于客户端不需要启动多线程即可完成并行调用多个远程服务,相对多线程开销较小。介绍 2.7 中的异步化改造之前,先回顾一下如何在 2.6 中使用 Dubbo 异步化的能力。

  1. 将同步接口声明成 async=true
<dubbo:reference id="asyncService" interface="org.apache.dubbo.demo.api.AsyncService" async="true"/>
public interface AsyncService {String sayHello(String name);
}
  1. 通过上下文类获取 future
AsyncService.sayHello("Han Meimei");
Future<String> fooFuture = RpcContext.getContext().getFuture();
fooFuture.get();

可以看出,这样的使用方式,不太符合异步编程的习惯,竟然需要从一个上下文类中获取到 Future。如果同时进行多个异步调用,使用不当很容易造成上下文污染。而且,Future 并不支持 callback 的调用方式。这些弊端在 Dubbo 2.7 中得到了改进。

Dubbo 2.7 异步化

  1. 无需配置中特殊声明,显示声明异步接口即可
public interface AsyncService {String sayHello(String name);default CompletableFuture<String> sayHiAsync(String name) {return CompletableFuture.completedFuture(sayHello(name));}
}
  1. 使用 callback 方式处理返回值
CompletableFuture<String> future = asyncService.sayHiAsync("Han MeiMei");
future.whenComplete((retValue, exception) -> {if (exception == null) {System.out.println(retValue);} else {exception.printStackTrace();}
});

Dubbo 2.7 中使用了 JDK1.8 提供的 CompletableFuture 原生接口对自身的异步化做了改进。 CompletableFuture 可以支持 future 和 callback 两种调用方式,用户可以根据自己的喜好和场景选择使用,非常灵活。

异步化设计 FAQ

Q:如果 RPC 接口只定义了同步接口,有办法使用异步调用吗?

A:2.6 中的异步调用唯一的优势在于,不需要在接口层面做改造,又可以进行异步调用,这种方式仍然在 2.7 中保留;使用 Dubbo 官方提供的 compiler hacker,编译期自动重写同步方法,请 在此 讨论和跟进具体进展。

Q:关于异步接口的设计问题,为何不提供编译插件,根据原接口,自动编译出一个 XxxAsync 接口?

A:Dubbo 2.7 采用采用过这种设计,但接口的膨胀会导致服务类的增量发布,而且接口名的变化会影响服务治理的一些相关逻辑,改为方法添加 Async 后缀相对影响范围较小。

Q:Dubbo 分为了客户端异步和服务端异步,刚刚你介绍的是客户端异步,为什么不提服务端异步呢?

A:Dubbo 2.7 新增了服务端异步的支持,但实际上,Dubbo 的业务线程池模型,本身就可以理解为异步调用,个人认为服务端异步的特性较为鸡肋。

三大中心改造

三大中心指的:注册中心,元数据中心,配置中心。

在 2.7 之前的版本,Dubbo 只配备了注册中心,主流使用的注册中心为 zookeeper。新增加了元数据中心和配置中心,自然是为了解决对应的痛点,下面我们来详细阐释三大中心改造的原因。

元数据改造

元数据是什么?元数据定义为描述数据的数据,在服务治理中,例如服务接口名,重试次数,版本号等等都可以理解为元数据。在 2.7 之前,元数据一股脑丢在了注册中心之中,这造成了一系列的问题:

推送量大 -> 存储数据量大 -> 网络传输量大 -> 延迟严重

生产者端注册 30+ 参数,有接近一半是不需要作为注册中心进行传递;消费者端注册 25+ 参数,只有个别需要传递给注册中心。有了以上的理论分析,Dubbo 2.7 进行了大刀阔斧的改动,只将真正属于服务治理的数据发布到注册中心之中,大大降低了注册中心的负荷。

同时,将全量的元数据发布到另外的组件中:元数据中心。元数据中心目前支持 redis(推荐),zookeeper。这也为 Dubbo 2.7 全新的 Dubbo Admin 做了准备,关于新版的 Dubbo Admin,我将会后续准备一篇独立的文章进行介绍。

示例:使用 zookeeper 作为元数据中心

<dubbo:metadata-report address="zookeeper://127.0.0.1:2181"/>

Dubbo 2.6 元数据

dubbo://30.5.120.185:20880/com.alibaba.dubbo.demo.DemoService?
anyhost=true&
application=demo-provider&
interface=com.alibaba.dubbo.demo.DemoService&
methods=sayHello&
bean.name=com.alibaba.dubbo.demo.DemoService&
dubbo=2.0.2&
executes=4500&
generic=false&
owner=kirito&
pid=84228&
retries=7&
side=provider&
timestamp=1552965771067

从本地的 zookeeper 中取出一条服务数据,通过解码之后,可以看出,的确有很多参数是不必要。

Dubbo 2.7 元数据

在 2.7 中,如果不进行额外的配置,zookeeper 中的数据格式仍然会和 Dubbo 2.6 保持一致,这主要是为了保证兼容性,让 Dubbo 2.6 的客户端可以调用 Dubbo 2.7 的服务端。如果整体迁移到 2.7,则可以为注册中心开启简化配置的参数:

<dubbo:registry address=“zookeeper://127.0.0.1:2181” simplified="true"/>

Dubbo 将会只上传那些必要的服务治理数据,一个简化过后的数据如下所示:

dubbo://30.5.120.185:20880/org.apache.dubbo.demo.api.DemoService?
application=demo-provider&
dubbo=2.0.2&
release=2.7.0&
timestamp=1552975501873

对于那些非必要的服务信息,仍然全量存储在元数据中心之中:

元数据中心的数据可以被用于服务测试,服务 MOCK 等功能。目前注册中心配置中 simplified 的默认值为 false,因为考虑到了迁移的兼容问题,在后续迭代中,默认值将会改为 true。

配置中心支持

衡量配置中心的必要性往往从三个角度出发:

  1. 分布式配置统一管理

  2. 动态变更推送

  3. 安全性

Spring Cloud Config, Apollo, Nacos 等分布式配置中心组件都对上述功能有不同程度的支持。在 2.7 之前的版本中,在 zookeeper 中设置了部分节点:configurators,routers,用于管理部分配置和路由信息,它们可以理解为 Dubbo 配置中心的雏形。在 2.7 中,Dubbo 正式支持了配置中心,目前支持的几种注册中心 Zookeeper,Apollo,Nacos(2.7.1-release 支持)。

在 Dubbo 中,配置中心主要承担了两个作用

  • 外部化配置。启动配置的集中式存储

  • 服务治理。服务治理规则的存储与通知

示例:使用 Zookeeper 作为配置中心

<dubbo:config-center address="zookeeper://127.0.0.1:2181"/>

引入配置中心后,需要注意配置项的覆盖问题,优先级如图所示

服务治理增强

我更倾向于将 Dubbo 当做一个服务治理框架,而不仅仅是一个 RPC 框架。在 2.7 中,Dubbo 对其服务治理能力进行了增强,增加了标签路由的能力,并抽象出了应用路由和服务路由的概念。在最后一个特性介绍中,着重对标签路由 TagRouter 进行探讨。

在服务治理中,路由层和负载均衡层的对比。区别 1,Router:m 选 n,LoadBalance:n 选 1;区别 2,路由往往是叠加使用的,负载均衡只能配置一种。

在很长的一段时间内,Dubbo 社区经常有人提的一个问题是:Dubbo 如何实现流量隔离和灰度发布,直到 2.7 提供了标签路由,用户可以使用这个功能,来实现上述的需求。

标签路由提供了这样一个能力,当调用链路为 A -> B -> C -> D 时,用户给请求打标,最典型的打标方式可以借助 attachment(他可以在分布式调用中传递下去),调用会优先请求那些匹配的服务端,如 A -> B,C -> D,由于集群中未部署 C 节点,则会降级到普通节点。

打标方式会收到集成系统差异的影响,从而导致很大的差异,所以 Dubbo 只提供了 RpcContext.getContext().setAttachment() 这样的基础接口,用户可以使用 SPI 扩展,或者 server filter 的扩展,对测试流量进行打标,引导进入隔离环境/灰度环境。

新版的 Dubbo Admin 提供了标签路由的配置项:

Dubbo 用户可以在自己系统的基础上对标签路由进行二次扩展,或者借鉴标签路由的设计,实现自己系统的流量隔离,灰度发布。

总结

本文介绍了 Dubbo 2.7 比较重要的三大新特性:异步化改造,三大中心改造,服务治理增强。Dubbo 2.7 还包含了很多功能优化、特性升级,可以在项目源码的 CHANGES.md 中浏览全部的改动点。最后提供一份 Dubbo 2.7 的升级文档: 2.7迁移文档 ,欢迎体验。

dubbo2.7.x相关推荐

  1. 构建Dubbo-2.0.7源码

    一. 下载源码: git clone --branch dubbo-2.0.7 https://github.com/apache/incubator-dubbo.git 二. 下载依赖 git cl ...

  2. Dubbo2.6.5入门——管控台的安装

    首先去下载管控台:GitHub 然后解压到本地,截止到目前2019-01-18,最新管控台基于Dubbo2.7.0-SNAPSHOT版本,但是2.7.0还没有正式发布,不过影响不大. Dubbo Op ...

  3. Dubbo---升级Dubbo2.7.13依赖问题

    版本对应关系表:https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E 20 ...

  4. Dubbo2.7.3入门

    2.7.X的Dubbo,包名不再是com.alibaba,而是org.apache 先看工程目录结构 一个公共api模块,一个SpringBoot项目充当Dubbo服务,一个SpringBoot项目充 ...

  5. 【dubbo-2.5.x】Linux下dubbo-admin监控/管理平台部署详细教程

    前言 Dubbo-Admin是Dubbo控制台管理的工具,是Dubbo组件之一,需要Dubbo-Admin管理平台来实时对服务调用情况进行调整,比如控制分布式服务的调用权重等,通过调整调整调用权重来控 ...

  6. dubbo2.4.11源码编译

    参:https://my.oschina.net/penngo/blog/494838 本文以dubbo2.4.11源码编译和打包例 dubbo官网:http://dubbo.io/ 源码:https ...

  7. 【Dubbo】Dubbo2.7新功能 --配置中心、元数据中心

    1.配置中心 配置中心提供了动态配置功能,是 Dubbo2.7 版本引入的一个新的功能. 简单来说,就是把 dubbo.properties 中的属性进行集中式存储,存储在其他的服务器上. 目前 Du ...

  8. springboot2.x+dubbo2.x+seata1.x AT+nacos+zk实现分布式事务

    Seata AT模式接入 目录 一.Seata AT模式介绍... 1 前提... 1 整体机制... 1 写隔离... 1 读隔离... 4 工作机制... 5 一阶段... 5 二阶段-回滚... ...

  9. 阿里的nacos+springboot+dubbo2.7.3集成以及统一处理异常的两种方式

    在网上很多关于dubbo异常统一处理的博文,90%都是抄来抄去.大多都是先上一段dubbo中对于异常的统一处理的原码,然后说一堆的(甚至有12345,五种)不靠谱方案,最后再说"本篇使用的是 ...

  10. Dubbo2.7文档详解

    本篇博文参考dubbo官方文档 本编博文参考javaguide之rpc 文章目录 一.RPC 1.1 什么是 RPC? 1.2 为什么要用 RPC? 1.3 RPC 能帮助我们做什么呢? 1.4 RP ...

最新文章

  1. 人工智能(5)---一文解读人工智能创业的5大坑
  2. Windows文件系统过滤驱动开发教程(0,1,2)
  3. 用数组存储二进制数据
  4. [CentOS Python系列] 六.阿里云搭建Django网站详解
  5. 【渝粤教育】 国家开放大学2020年春季 1009离散数学(本) 参考试题
  6. vue 判断对象不为空_Vue 学习笔记(二):实例
  7. 破解wifi并实施中间人攻击
  8. 安装Kali Linux系统
  9. redhat红帽官方软件仓库同步方案
  10. js骚操作骂人不带脏
  11. 新入职公司离职率高怎么办
  12. 细化算法matlab
  13. 解决知乎页面打印时下方文字被遮挡的问题
  14. Rust图片类型识别
  15. 基于asp.net721运动体育商城
  16. SI5351A的信号发生器驱动程序
  17. python中setup是什么意思_python中setuptools指的是什么
  18. Android ndk 编译出现'Build Project' has encountered a problem.Errors occurred during the build
  19. 从流水线工人,到谷歌上班的程序媛,一位湖南娄底妹子的励志故事...
  20. DSP TMS320F28377D与TMS320F28335硬件资源对比

热门文章

  1. docker部署项目通过127.0.0.1访问数据库:Connection refused
  2. Pix4飞控硬件平台框架(一)
  3. 移动游戏的新推广模式
  4. PmxEditor制作mmd表情
  5. 同一个ssh key用在多台电脑上
  6. java水果爆炸动画_5分钟快速实现Android爆炸破碎酷炫动画特效的示例
  7. Matlab map工具箱的使用
  8. 沈阳服务器主板维修,沈阳铁西区附近电脑主板维修
  9. pic 18f45k80单片机看门狗程序
  10. 【深度学习】经典神经网络 VGG 论文解读