当前位置:   article > 正文

阿里技术专家详解Dubbo实践,演进及未来规划_阿里doubble

阿里doubble

Dubbo 整体介绍

Dubbo 是一款高性能,轻量级的 Java RPC 框架。虽然它是以 Java 语言来出名的,但是现在我们生态里面已经有 Go、Python、PHP、Node.JS 等等语言。在 GitHub 上,https://github.com/dubbo 下面已经有很多生态相关的东西。

 

Dubbo 是一个 RPC 框架,它和所有的 RPC 一样,有一个最小运行子集,它需要 Provider、Consumer,以及一个服务注册发现相关的东西,在 Spring Cloud 里面是叫服务注册发现,在 Dubbo 里面我们叫它注册中心(后面讲到东西我们都以注册中心来进行说明)。

简单介绍一下 Dubbo 的整个启动过程:

Provider 导出一个服务,这个服务就是可被调用的;

第二步,往注册中心注册这个服务;

Consumer 这端会来订阅相关的服务,如果注册中心里面,Provider 列表有变化的话,它也会得到通知;

Consumer 会根据一定的路由规则从注册中心拿到 Provider 列表,再根据一定的负载均衡策略,精确地调用到某台 Provider 上去。

这就是一个简单的一个 RPC 的调优过程。

Dubbo 在 2011 年就在 GitHub 上进行了开源,经历了很多年的发展,整个社区一直非常活跃,现在 GitHub 上 Star 数已经高达 23K+,Fork 数 16K+。

在 2018 年 2 月份的时候,阿里巴巴已经把 Dubbo 的项目捐献给了 Apache 社区,希望更多人能够参与到 Dubbo 开发中来,希望依靠集体的智慧让 Dubbo 变得越来越好。现在 Dubbo 的 committer,外部开发者的人数已经多于阿里巴巴开发者,包括微店,网易云音乐,考拉,韩都衣舍等等。

Dubbo 因为开源这么多年,积累了较多的用户,包括很多互联网的企业,包括阿里巴巴,考拉,滴滴等互联网企业;还有很多中字头企业,中国电信,中国人寿,中国工商银行;还有一些比较传统的企业。

Dubbo 的实践和演进

Dubbo 服务注册

背景知识介绍

在 RPC 整个链路中,需要的元素有 Provider、Consumer,以及注册中心(中间 Zookeeper 是作为注册中心来使用的)。整个注册过程如下:

Provider 会把一长串 URL(dubbo://xxx 的字符串)写入到 Zookeeper 里面某个节点里面去。

Consumer 的注册也是类似,会写到 Zookeeper 里面某个节点(Consumer 写入的原因,是因为 OPS 服务治理的时候需要实时的消费者数据)。

Consumer 发起一个订阅,订阅相关的服务。

当某个服务的 Provider 列表有变化的时候,Zookeeper 会将对应的变化通知到订阅过这个服务的 Consumer 列表。

从图中我们可以看到 Provider 端的 URL 非常长,特别是当一个服务有大量方法的时候。Provider 端的 URL 会先从 Provider 到 Zookeeper,再往 Consumer 传递,这样导致了单次传输的网络开销比较大。

那么再来看一下集群的情形,图中左边有 N 个 Provider,右边有 M 个 Consumer,那么 Provider 发布的时候,会遇到什么情形呢?Provider 每次发布它会先下线再上线,所以每个 Provider 发布的时候,Provider 会发送两次通知,也就是发送 2N 次;接收数据方有 M 个 Consumer,最后算出在整个网络里面的推送数据的次数是 2N×M。

案例

来看一个真实的案例,在杭州有一家中等规模的电商公司,公司内部有 4000+ 个服务,以 Zookeeper 作为注册中心,Zookeeper 有 100w 个节点,在发布日的时候,公司内部网络的网卡被打爆了,进而导致服务变更的推送失败,新的服务注册也失败。整个集群基本上处于不可用状态。同样的也收到了一些中小公司的反馈,每次在发布的时候,网络也会有个抖动。

分析一下为什么会出现这种情形。

Zookeeper 的 100 万节点中,大约有 10 万个 Provider 节点和 50 万个 Consumer 节点。按照前面的算法,在所有 Provider 同时发布的极端情况下,有 2×10 万×50 万次推送,也就是说会产生 1000 亿条的数据推送。针对每次推送的数据进行了一个统计,每条 URL 大小大概有 1KB,那么计算出来的极端的推送数据量是 1KB 再乘以 1000 亿,已经是 100TB 的级别了。

上面说的是极端情形,就算是发布日也不可能同时进行发布:有的应用发布日不发版本,不同应用不可能同时发布,同一个应用也需要分批发布。假设同一时刻发布的量在千分之一,那么推送的数据量也在 100GB,所以出现发布日的时候间断性地网卡爆掉的现象就不足为奇了。每次发布的时候,都会想着要跟别的应用发布时间错开,争取单独发布,作为程序员还要纠结这个事情真是一个悲剧。

案例分析

来分析下现在的问题和需求:

首先,根据上述案例中的数据分析得知,性能出现了问题。推送的数据量非常大,存储的数据量大,网络传输量大,服务推送延迟,网卡堵塞,服务注册不可用。

接着对 Provider 端那个很长的 URL 进行分析之后发现,不需要把整个 URL 写到注册中心里,只需要把 IP 的端口写进去就可以了,因为只有 IP 的端口需要实时变化。把其他信息放到一个类似的 KEY-VALUE 结构的持久化存储里去,而且这个 KEY-VALUE 结构只要是应用级别就行了,节省了大量的存储空间。

社区中对服务测试的需求非常强烈。要支持服务测试需求,就需要知道调用的服务方法名,入参出参的详细信息。所以这部分信息也是需要存储下来的。但是这部分信息非常大,每个服务中可能有 10 多个方法,每个方法可能有三四个方法入参,入参和出参的完整数据结构往往非常复杂。这部分数据信息也叫做服务的元数据信息。

首先来看一下怎么解决性能的问题。主要有两种方式可以解决:

怎么减少当次的注册量,就像前面分析的,只存储 IP 的端口到注册中心;

是否可以减少推送的次数,现在推送次数太大了。

减少单次推送量

 

查看上图可知,Provider 端 URL 还是很长,期望简化往注册中心注册的信息;同时服务测试需求,又同时期望能将更丰富的元数据信息进行持久化的存储。

Provider 端写入的改造。Provider 往注册中心写的时候,将整个数据的写入分成两部分:

写入注册中心;

写入元数据中心。

注册中心作为服务的注册和发现,更加关注数据的实时性和有效性 (watch 机制),整个 URL 中 IP 和端口就能判断某个服务是否可用,其他信息都是相对固定不变的。所以注册中心中,只需要存储 IP 和端口。元数据中心中存储 URL 中除 IP 和端口外的其他信息,加上服务测试需要的服务方法名,服务方法的出入参信息。元数据是一个 KEY-VALU

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/166133
推荐阅读
相关标签
  

闽ICP备14008679号