Dubbo 实践,演进及将来规划

Dubbo 总体介绍

Dubbo 是一款高性能,轻量级的 Java RPC 框架。虽然它是以 Java 语言来出名的,可是如今咱们生态里面已经有 Go、Python、PHP、Node.JS 等等语言。java

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

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

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

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

  • Consumer 这端会来订阅相关的服务,若是注册中内心面,Provider 列表有变化的话,它也会获得通知;sql

  • 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 是做为注册中心来使用的)。整个注册过程以下:

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

  2. Consumer 的注册也是相似,会写到 Zookeeper 里面某个节点(Consumer 写入的缘由,是由于 OPS 服务治理的时候须要实时的消费者数据)。

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

  4. 当某个服务的 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 多个方法,每一个方法可能有三四个方法入参,入参和出参的完整数据结构每每很是复杂。这部分数据信息也叫作服务的元数据信息。

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

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

  2. 是否能够减小推送的次数,如今推送次数太大了。

减小单次推送量

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

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

  • 写入注册中心;

  • 写入元数据中心。

注册中心做为服务的注册和发现,更加关注数据的实时性和有效性 (watch 机制),整个 URL 中 IP 和端口就能判断某个服务是否可用,其余信息都是相对固定不变的。因此注册中心中,只须要存储 IP 和端口。元数据中心中存储 URL 中除 IP 和端口外的其余信息,加上服务测试须要的服务方法名,服务方法的出入参信息。元数据是一个 KEY-VALUES 的持久化存储,是独立于注册中心的存储,它不须要有 watch 的机制,而只须要提供持久化存储。图中使用的的 KEY VALUE 存储是 Redis,可是元数据中心定义了一套 SPI,开发者能够去扩展,能够本身实现 DB 存储,或者其余持久化存储的方式。

Consumer 端获取 Provider 列表信息的改造。Dubbo 以前的版本中,直接从注册中内心面获取 Provider 端的服务信息,获取到的信息已是一个完整的可调用的服务信息。可是 Provider 端写入改造以后,原有 Consumer 端获取的 Provider 服务信息的方式不可用了。除了从注册中心获取到的数据以外,还须要从元数据中内心拿到元数据信息,而后对这两部分数据作一个 Merge 以后才能构建出完整的可调用的服务信息。

当前 Dubbo2.7 版本尚未彻底去除全部参数,而是采用先去除部分参数的方式来验证;后续会逐渐迭代完善,同时在 2.6.x 版本中也会进行一些兼容方案的支持。

应用级服务注册

上面的改造针对的是怎么减小单次的推送数据量,针对的仍是服务维度。指望中最理想地给注册中心减负的方式是应用维度的服务注册和发现,能够参考 Spring Cloud 体系下的 Eureka 实现。一旦实现这种方案,服务注册中心就不再会成为 RPC 领域的瓶颈,并且能够认为这种方案是服务注册的终极方案

固然这种实现方式作的改动相对比较大,不只须要将服务执行和运维彻底分开,并且须要必定的架构体系改造来支撑具体服务的发现。到目前为止尚未造成成熟可靠的方案,团队内部也只是在探讨阶段。

服务变动推送开关

所谓服务变动推送开关,就是针对任何的服务信息的变动,不进行推送。

到底哪一种情形须要这种开关呢?阿里巴巴整个集群的机器数很是大,因此宿主挂掉或者虚拟机挂掉出现的几率比较高。在每一年双十一的时候,大部分消费者都会去淘宝天猫上购物。在 11 月 10 号 11 点 50 几分开始,大量买家在拼命地刷新购物车或者商品详情页面,这时候阿里巴巴内部的系统负载是很是高的,网络负载也很是高。若是这时候,有一台机器由于宿主机挂了的缘由而致使部分服务下线,这时候须要推送相关应用服务下线的变动给对应的服务 Consumer。这时候就须要占用网络带宽,可能对服务调用产生影响,进而还会对双十一形成很大的压力。因此这时候就但愿有一个开关,可以把整个服务推送关掉。

可是这时候也会带来一些问题,当服务 Provider 不可用的时候,注册中心没有向服务 Consumer 推送变动通知,服务 Consumer 请求的时候可能会报错,这时候的小部分服务出错能够容许的;保证整个集群上万台机器,特别是整个双十一核心链路的稳定性才是双十一最重要的使命。

服务分组

在一个大的集群环境中,在没有路由规则的状况下,Consumer 集群会调用整个 Provider 集群中的任何机器。服务分组,就是对 Consumer 集群和 Provovider 集群进行分组,将大的服务级分红几个子集。

举个例子,集群中有 8 个 Consumer 实例,有 8 个 Provider 实例,按照正常流程 Consumer 这 8 个实例会调用 Provider 任何一台,任何一个 Provider 的变动通知也会通知到这 8 个 Consumer 实例。可是若是对它进行分组呢,Consumer 实例集群分红 A 和 B 两个组,Provider 集群也分红 A 和 B 两个组。Consumer 中 A 的组只能调到 Provider 中 A 组的服务;Provider 的 A 组中的实例在发布过程当中,也只会推送到 Consumer 的 A 组中,而不会推进 Consumer 的 B 组。最终经过推送的范围,来减小了推送的数据总量。

对于服务分组的的实现,这里不作展开,本文后面再次讲到服务分组的时候,会稍微展开陈述。

服务注册中心

前面陈述的服务注册相关的改造和方案,都是围绕 Dubbo 等 RPC 进行的。接着来看一下在互联网环境下,理想的注册中心是什么样子的。(如下阐述只表明我的观点)

CAP 理论:如今大部分主流并且在使用中的注册中心都是知足 CP 的,可是在互联网大集群环境下,指望的结果是知足 AP 的同时,可以知足最终一致性。在大集群环境下,可用性每每比强一致性的优先级更高。以 Zookeeper 为例,Zookeeper 可以为分布式系统提供协调功能的服务,默认提供强一致性的数据服务,可是它在某些状况下是容许 Zookeeper 是不可用的。列举一个场景,Zookeeper Leader 失效了,这时须要从新选举 Leader,而这个选举过程须要 30 秒以上 (数据来自于网上的文章),这段时间内 Zookeeper 对外是不可用的。

去中心化:Zookeeper 是有 Leader 机制,往 Zookeeper 里写数据都是往 Leader 里面写,这个 Leader 其实就是一个单点。因此整个写的过程是中心化的。并且 Zookeeper 对跨城跨机房的方案上,支持很是有限。

数据推送的强控制:指望对推送的有更增强的灵活性。仍是以 Zookeeper 为例,Zookeeper 中有 watch 机制,每一个数据节点发生变动的时候,就会往外推送变动的通知。可是做为注册中心,咱们指望可以控制它的推送频率,针对新增节点只须要一分钟里面推送 6 次就能够了,每十秒推送一次,这样能够合并一些变动通知,减小网络数据请求的数据量。

容量:Dubbo 是单进程多服务的方式来注册服务的。这也就意味着注册中心中须要存储的数据量较大,因此要有足够的容量来支撑这种场景。

那些注册中心产品:Zookeeper 做为服务注册中心的公司在减小,那么如今有哪些方案,能够来替代呢?

Eureka是一个 AP 的应用,并且它是去中心化的。可是它有几点不足:

  1. 在咱们的内部的性能测试中,它性能表现很是通常,性能大概只有 Zookeeper 的 60% 左右。

  2. Eureka 内有一种契约机制,它每隔 30 秒会发起一个续约的请求,若是 3 次没有接收到,它才会过时失效;若是一个服务非正常退出(没有发起解约请求),那么就存在这个超时的间隙期,服务是不可用的。因此在生产环境,对服务敏感的相关应用方是没法知足需求的。

  3. Eureka 是应用维度的服务注册,当前的 dubbo 是服务维度的注册,若是要匹配的话,须要大范围改造。

  4. Netflix 宣布了中止更新 Eureka 2.0。

Etcd是 Zookeeper 的升级版,它参考了 Zookeeper 的不少实现,同时进行了较多优化。Etcd 的强一致性协议和代码实现更加简单,它的部署方式也更加简单,它支持了 Rest 的方式进行相关访问,它的性能相对 Zookeeper 来讲也有了必定的提高。可是它仍是一个 CP 的系统,它也是要求数据的强一致性,而牺牲部分的可用性。

Consul相对前面几个产品来讲,更加专一服务注册发现自己,它是一个比较专业的服务注册中心。Consul 有了后台管理页面,它有了健康检查,Consul 原生支持多数据中心。但它的性能上有瓶颈的,它和 Zookeeper 和 ETCD 进行对比,它性能是稍微差一点的;同时 Consul 也要求数据的强一致性而牺牲部分可用性。

Nacos是阿里巴巴开源的一个产品,内部系统也在使用,它已经经受了必定流量和用户的考验。如今阿里巴巴集团内部的 Provider 和 Consumer 数量已经到达了亿的级别,它如今可以支撑上亿级别的订阅量,总体经受了必定的实践检验。Nacos 总体设计是去中心化的,并且设计上知足 AP 和最终一致性,性能上和 Zookeeper 比较接近。

前段时间和网易考拉在沟经过程中也发现,他们也在作一个本身的注册中心;新浪也有一个本身的服务注册中心。因此许多大的互联网公司,由于定制或者差别化的需求,都在自研注册中心。

配置中心

当前困境

应用开发者

Dubbo 内部有一个配置文件叫 dubbo.properties,这种配置方式和 Spring Boot 的 application.properties 是比较像的。每次新开发一个 Dubbo 应用的时候,应用开发者都须要去写一大堆的配置到 dubbo.properties 中,包括注册中心的地址,元数据中心的地址,应用级别的超时时间等等。当所在公司只有两三个应用的时候,一个个应用单独设置的方式是没问题的;当业务快速发展的时候,应用数从 2 个变成 20 个应用的时候,那么所在的技术团队可能须要整理一份快速构建应用的文档,供应用开发者参考使用,并且这个文档须要及时维护更新。若是这时候还须要更改注册中心地址(原来 2 个应用的时候,Zookeeper 的地址用 IP 来快速实现,如今想换成域名了),意味着要去推进这 20 个应用的开发者,让他们修改对应的配置,而后测试而且发布。整个过程很是痛苦!须要有一种相似于 Spring Cloud Config 的配置方式来知足集中式的配置方式,至关于一个远程集中式的 dubbo.properties。

Dubbo 开发者

Dubbo 2.7 之前的版本中,服务路由规则,服务治理规则的数据都是存储在注册中心中的。以前大部分用户都选用 Zookeeper 做为注册中心,Zookeeper 兼具了 Key-Value 的功能,因此以前的版本中运行起来是没有问题的。 可是若是选用的注册中心,不具备持久化的功能,这时候的路由规则和服务治理规则就没地方存储了,整个系统就玩不转了。做为 Dubbo 开发者,指望将服务治理和服务路由规则分开存储到一个集中式的 Key-Value 存储中。

要解决上述两个痛点,须要在 Dubbo 中引入一个远程的集中式的配置中心,这个配置中心存储了远程的 dubbo.properties,路由规则,服务这里规则等。

欢迎欢迎学Java的朋友们加入java架构交流: 855835163

应用架构师

举个场景,一个公司的全部应用已经引入了 ETCD 做为本身的应用的动态配置管理,可是在引入 Dubbo 之后,Dubbo 中又有几套对应的动态配置可供选择,如 Nacos、阿波罗,Zookeeper。这就要求公司层面须要维护两套动态配置的 Server,这个成本比较高,并且增长了系统的稳定性的风险。对于架构师来讲,须要 Dubbo 能支持 ETCD 的动态配置。

解决方案

图中分红上下两部分,下面黄色部分就是它的一个存储;上面的整个部分是 Dubbo 内部实现。上文中所讲的动态配置,在 Dubbo 中定义为配置中心。

在实现层面,在 Dubbo 中定义了一层 SPI,默认实现的 Zookeeper,Apollo,Nacos。应用架构师去扩展这个 SPI 就能够完成 ETCD 的定制,这样就能达到和原有的应用中使用 ETCD 方式兼容。

对于运维工程师来讲,原来的一个注册中心的地址变动要推进每一个应用开发者去作变更,应用开发者很是烦,运维工程师很吃力。如今只须要在远程的 dubbo.properties 里进行统一去升级,而后通知相关的应用开发者进行一些适当的验证。

由于已经定义了配置中心的 API,Dubbo 开发者直接调用对应的 API 来实现服务规则和路由规则的存储。

三个中心

三个中心就是前面讲到的注册中心,配置中心,元数据中心。

指望的使用方式:Provider 先去配置中内心获取注册中心的地址和元数据中心地址,再根据拿到的注册中心地址去对应的注册中心注册服务,根据拿到的元数据中心地址写入元数据信息到对应的元数据中心 Server。Consumer 和 OPS 也是相似的。

经过配置中心这种集中式的配置方式,可让开发者从原来烦琐的配置中解脱出来,让它更聚焦于业务的开发,而不须要关注框架层面的东西。

路由规则

路由规则组合

Dubbo 路由规则,按照覆盖范围可分为应用级别,服务级别,方法级别路由规则;按照功能纬度,能够分为黑名单,条件路由 ,TAG 路由规则。大部分路由需求都是能够经过组合来实现的,如应用级的黑名单能够经过应用级别 + 黑名单路由规则方式组合。

全链路灰度发布

某产品新开发了一个新特性,想进行 A/B Test,让部分用户开放新功能体验;或者产品在迭代过程当中,想进行下改造功能的灰度验证。在当前微服务的架构体系下,一个新功能每每依赖整个调用链路的上下游一块儿完成。因此这两种新功能的验证,基本不可能在单机上完成,每每须要服务链路的上下游一块儿隔离出一部分机器进行验证。在这里,称为全链路灰度发布验证。

来看一种最简单的场景。客户在浏览器端发起一个 HTTP 请求,这个请求会根据一个负载均衡策略访问到一台 web 服务器 (30.5.127.44),这台机器会调用服务 A 集群,服务 A 集群会调用服务 B 集群。业务开发者开发了一个新功能,想在线上验证功能的正确性,可是又不想原有的功能受影响。也就是说想从服务集群里拿出少部分实例去验证线上的功能。假设下需求,但愿总用户的千分之五的用户可以走到新功能的流程,帮助验证新功能的正确性。

  • 从服务 A 集群中选出一台机器(30.5.120.16)做为灰度验证的机器,从服务 B 集群中选出一台机器(30.5.128.66)做为灰度机器。对选出的这两台机器打上标canary(金丝雀)。

  • 须要在 Web 服务器运行的代码逻辑中,增长逻辑:获取到用户的 UserId,UserId 对 1000 求模以后小于 5 的,在 Dubbo 对服务 A 集群发起请求以前带上 Tag=canary(在 Dubbo 中是经过设置 Attachment 来完成)。

  • Dubbo 自带的 Tag 路由规则会作如下事情:Dubbo 会先拿到要调用服务所在的应用名;再根据应用名 +Tag 路由规则的名称 canary, 去获取到对应的机器列表,Web 服务就拿到了 30.5.120.16 这台机器;Dubbo 根据拿到的机器列表依据负载均衡策略发起请求。相应的 Web 服务器中没有打上标的机器,会访问到其余机器 (30.5.120.26),而不会访问到已经被打上标的机器。Tag 路由规则,完成了对相应 Provider 和相应 Consumer 端的隔离。

  • 经过 Tag 路由规则已经解决了 Web 集群到服务 A 集群这里面的链路,可是怎么解决服务 A 集群到服务 B 集群的 Tag 的传递呢?如今比较流行的一些全链路跟踪的产品能够帮咱们作到,如 Open Tracing,Zipkin。咱们以 Zipkin 为例,经过 Zipkin 实现 Dubbo 的 Filter 能够把这个标从 Web 集群传到服务 A 集群再传到服务 B 集群,整个链路均可以传递下去。

  • 总体调用链路总结。知足灰度验证的用户链路:web 服务 -> 30.5.120.16 -> 30.5.128.66; 不知足灰度验证的用户 (不打标) 链路:web 服务 -> 集群中 30.5.120.16 以外的机器 -> 集群中 30.5.128.66 以外的机器。

经过上述步骤已经完成了全链路的灰度环境搭建,这种方式的应用范围很是广,能够按照本身的业务场景和需求进行一些调整来达到本身指望的效果。下面集群中也有案例进行说明。

集群

从集群角度来看下,服务实例之间的隔离。假设一个 Provider 集群有 8 个实例,Consumer-A 集群有 4 个实例,Consumer-B 集群有 4 个实例; Consumer-A 集群和 Consumer-B 都会调用 Provider 集群。

服务分组:以 Provider 和 Consumer-A 为例。将 Provider 分红左 (一、二、三、4) 和右 (五、六、七、8) 两个组,将 Consumer-A 分红左 (一、2) 和右 (三、4) 两个组。Consumer-A 中左组只能调用到 Provider 中的左组,Consumer-A 中右组只能调用到 Provider 中的右组,而不会调用到整个集群的其余实例。服务分组除了能让注册中心减小推送的数据量外,还能减小 Consumer 和 Provider 长链接的数量,从而带来必定的性能提高。

服务分组最简单的实现方式,在 Dubbo 的 Service 和 reference 中配置中配置多个 group,进行手动匹配。

更高级的服务分组实现方式,经过路由规则的方式进行动态匹配,路由规则中根据必定的规则(如根据 Ip 的最后位的奇偶数)将 Provider 和 Consumer 进行分组,而后路由规则里去完成隔离。这种方式暂时尚未发现较好的实现。

业务隔离:来看个现实的场景,阿里巴巴交易平台承接的业务很是多,在新零售出来以前,全部的业务都是线上交易,在出现 2 分钟的不可下单的时候,体验糟糕可是还不会引发大范围的骚乱。可是在盒马鲜生线下购物的时候,若是出现 2 分钟不能下单,那在排队的消费者意味着要干等两分钟,这是很是糟糕的体验。

抽象下上面的场景,用更加产品化和技术化的方式来分析。以 Provider 和 Consumer-A,Consumer-B 为例。Provider 集群的消费者很是多,包括 Consumer-A,Consumer-B 或其余 Consumer 集群。由于 Consumer-B 的业务很是重要,不想让其余机器的故障,影响到 Consumer-B 的稳定性,因此 Provider 中来自于 Consumer-B 的流量须要进行隔离。业务隔离的实现方式,能够采用 Tag 路由规则的方式来实现。对 Provider 集群的 7,8 机器打上标 -BTag(即路由规则,能够经过 OPS 打标),而后在 Consumer-B 集群中调用 Provider 以前 setTag=BTag (在 Dubbo 中在 attachment 里设置 tag 值)。

灰度环境

单机灰度的话,只要在发布的时候,能够单台机器发布就能够。

全链路灰度,须要在整个集群中圈出一批机器,如从 Provider,Consumer-A,Consumer-B 集群中选出 3 号机器做为灰度环境。全链路灰度的实现已经在前面说明,用 Tag 路由实现。

服务测试

Dubbo 服务测试

Dubbo 在启动时,会导出服务,让服务是可被调用的;同时它还会向元数据中心写入元数据信息(包括服务方法的方法名,路参,出参等信息)。

服务测试是在 Dubbo OPS 后台中的功能。服务测试业务流程:先去元数据中心获取元数据信息;在页面中展现服务的结构体,等待用户输入;用户输入参数信息;Dubbo OPS 后台根据元数据信息和用户输入的参数构造出服务调用的入参,向相应的 Provider 发起泛化调用。泛化调用被较多的网关系统使用。

Swagger 整合

除了服务测试功能外,还须要:

  • 文档功能。自动生成文档,生成的文档是可视化的,而不是 JSON 等文件格式。

  • 自动化测试。

Swagger 能够知足以上需求。可是 Swagger 和 SpringMVC 结合紧密,SpringMVC Rest 接口加上注解以后,能够快速整合 Swagger。

要让 Dubbo 可以经过 Swagger 方式生成文档和进行自动化测试,须要作两个事情:

将 Dubbo 接口形式转换成 Swagger 文档。Swagger 是有文档规范的,只要将接口形式转换成 Swagger 约定的格式,就能够知足 Swagger 文档的形式进行输出。

Swagger 服务测试功能。外部 HTTP 请求到一个 Controller,Controller 须要将 HTTP 请求转换成 Dubbo 请求,包括参数的映射和服务的映射。

服务治理

Hystrix 停更

Hystrix 停更了,在 GitHub 官网上推荐了 Resillence4j,阿里巴巴也开源了 Sentinel。这里进行一个简单的比较。

Hystrix 的两块功能,隔离和熔断,能知足大部分需求可是中止更新了。

Resillence4j 要求 JDK8 及以上,对 function 编程更加友好。

Sentinel 在阿里内部使用的范围很是广,已经经受住了必定的考验。每一年双十一在买东西的时候,若是出现一个页面上显示系统繁忙请稍候重试,或者显示人太多了请排队,这时候其实就是 Sentinel 在后台发挥做用了。Sentinel OPS 这块作得很是好,达到了开箱即用的标准。

服务治理清单

不要设置应用级别重试

在 Consumer 端设置重试,必须保证 Provider 端屡次调用是幂等的。

设置应用级别的重试,会让已经压力倍增的系统雪上加霜。举个例子,Provider 系统的线程数是 200,当 Provider 某个服务出现问题,致使 RT 从 200ms 变为了 3500ms;Consumer 由于设置了默认重试且重试次数为 3,这就会致使 Provider 线程池很快会被耗尽。

因此,默认不要设置应用级别的重试,对有业务需求的服务单独设置重试的规则,而且保证 Provider 端服务的幂等性。

设置超时时间

设置超时时间,可以防止系统雪崩和资源耗尽。一个 Consumer 调用 Provider 的时候,Provider 须要 3 秒处理完业务逻辑以后返回结果,Consumer 默认是同步调用,须要某个线程同步阻塞等待 3 秒,也就是说若是没有超时机制,很容易将 Provider 的问题传递给 Consumer 而且不断往上传递。若是 Consumer 设置了超时时间 200ms,Provider 加入须要 3 秒处理完结果,可是不会将问题传递给 Consumer。

建议的超时时间是一百毫秒到两百毫秒左右,对于特殊业务进行特殊设置。

隔离

隔离包括实例隔离和线程隔离。实例隔离,就是前面讲到的服务分组和业务分组,经过实例隔离达到问题和影响面的隔离。

线程隔离,能够分为静态隔离和动态隔离。静态隔离,首先经过必定的分析方法找出一些比较慢的方法,或者甄选出业务上比较重要的服务方法;再对这些服务或者方法单独设置线程池以及对应的线程个数。动态隔离是在 Dubbo 应用运行态的时候,自发地调整线程池的隔离。Dubbo 应用里默认的线程数是 200 个,200 个消耗完以后,新的请求进来就会返回线程池满的异常。这时候 Dubbo 内部会对运行中的服务方法进行统计,统计出并发线程数 >8,RT>300ms(假设的一个指标) 的服务,把这些服务扔到独立的线程池里去完成,后续这些服务的执行都会由这些新建的线程池的线程执行,其余服务仍然在这 200 个线程池里面执行。当这些隔离的服务方法运行一段时间后,它的 RT 变得正常了,那这部分独立出去的线程池能够被销毁,这些服务方法能够从新由原来的 200 个线程执行。整个过程的调整是动态的。整个动态隔离的机制和 Hystrix 的线程隔离有些相同的含义。

治理工具

每一个微服务实践的时候都会讲到。微服务最佳实践里面,强链路跟踪,限流,降级、熔断等,均可以在系统里引入,进而保证系统的稳定性。

系统可验证

系统可验证主要包含两方面,第一个是环境是可被验证的;第二个是经过必定的测试手段和方法来保证系统是可测试和可验证的。

环境可被验证,有些场景须要支持单机的灰度,有些场景须要全链路的灰度。

测试方面:在系统上构建接口级别的服务测试,自动化测试,支持全链路压测。经过服务测试和自动化地执行来加强系统的正确性测试;经过全链路压测,来判断全链路的瓶颈在哪里。

Service Mesh

Service Mesh 在 2018 持续火热,阿里巴巴和蚂蚁都在这一块有布局。如今阿里内部主要在两个场景中去作尝试,第一个是跨语言。阿里大部分语言是 Java,可是有少部分是 C++,还有部分 NodeJS,须要 Service Mesh 去解决跨语言之间的调用。第二个是异构系统。阿里巴巴收购了一些公司,但收购进来公司的技术栈和集团内部不一致,它多是 Java 语言,可是使用的 Spring Cloud 的微服务体系,还有一些公司没有使用 Java 语言,须要经过 Service Mesh 来解决这种异构系统之间的调用问题。

从实现方式上来讲,阿里没有重复的造轮子,控制层这一块(也被称为 sidecar),是在 Envoy 上进行了一些扩展,实现了一个 Dubbo Filter,如今这部分代码已经被捐献到了 Envoy 的社区。数据层实现方式是对 Istio 作了一些扩展和定制。由于 Istio 有一套默认的服务发现,服务治理的产品,但阿里巴巴有本身的服务发现,动态配置管理,服务治理的产品方案。在数据层,会将 Istio 和阿里巴巴中间件的产品作一些整合,来知足需求。

从部署结构上看,Dubbo 应用和对应的 Envoy 实现是部署在一台机器上 (虚拟机) 的,只是以两个进程的形式存在。Dubbo 应用须要调用 Spring MVC 应用中的服务,每一次发起调用的时候,Dubbo 应用会首先调用到同一台机器上的 Envoy 进程,再调用到另一台机器上的 Envoy 进程,另一台机器的 Envoy 进程再调用 SpringMVC 应用。整个调用过程多了两跳。

阿里巴巴已经在咸鱼的一些场景上在作 Service Mesh 的验证,同时程序和架构也在持续优化过程当中。

Dubbo 现状和将来

当前工做

核心特性

针对 2.7 以前存在的若干异步问题进行了优化。在 Dubbo2.7 以后,开始全力拥抱 JDK8。因此 2.7 版本将基于 JDK8 中的 CompletableFuture 作出一些针对性的加强来支持异步,相似于 Promise 方式。

优化服务治理参数配置,升级服务路由规则,同时对应的 OPS 也进行了相应的升级。Dubbo2.7 以前的路由规则对应关系一个服务能够对应多条规则,优化以后一个服务只能对应到一条规则;新增了前文讲到的 Tag 路由;服务治理参数,路由规则的数据存储都将使用配置中心。

社区里面分支演进分红 2.6 版本和 2.7 版本。2.7 版本主要有一些新功能的迭代,2.6 以维护为主。若是 2.7 里有些功能能够被 2.6 借鉴的话,也会往 2.6 里面叠加。

Spring Boot

新增了一个工具页面,用于快速构建 Dubbo 的 Spring Boot 的应用。这个参考了 Spring Boot 的模式。

在 Dubbo 体系下,有一个 Dubbo Spring Boot 工程来支持 Dubbo+Spring Boot 的整合。到目前为止支持 Dubbo2.6.X 版本,支持 Spring Boot 1.5.x 和 2.0.x。由于 Spring Boot 的 1.5 和 2.0 的分支差距比较大,因此 Dubbo Spring Boot 也维护了两个版本。后续 Spring Boot 1.X 会在 2019 年中止更新。

Dubbo OPS

Dubbo OPS 进行了全新的升级,有了一个新的 UI,合并了 Dubbo Admin 和 Dubbo monitor 两个应用,并且整个 OPS 用了 Spring Boot 工程结构,从而真正达到了开箱即用。Dubbo OPS 可以同时支持 2.6 和 2.7 的版本的运行,对新功能进行了相应的配置支持。

开源建设

Dubbo 捐献给了社区以后,从新搭建了新的官网,新的中英文文档,有了中英文博客,整个社区如今很是活跃。在这半年多依赖,和一些深度使用 Dubbo 的客户作了一些交流,如工商银行,考拉等等。今年举办了 5 场 Meetup,包括杭州,成都,深圳,北京,上海,吸引了大量的开发者参与。

生态建设

  1. 正如前面所说,在多语言方面,社区引入了 PHP,Go,NodeJS,Python 等。

  2. 对现有的一些生态组件进行持续升级和维护。

  3. 引入了一些新的扩展组件,包括 SkyWalking,ETCD 等等。

将来规划

社区投入

社区持续投入,包括 PR,Issue 跟进,优秀博客和文档的持续输出。固然整个运做形式是根据 Apache 的方式进行运做,而 Apache 沟通的最主要形式就是邮件,因此各开发者能够订阅 Dubbo 的邮件列表进行持续跟踪。

持续推动 Dubbo Meetup 和客户交流。

功能加强和 Issue 跟进

持续功能加强和优化,包括前面的注册中心的优化,路由规则的持续加强和优化。如今 Dubbo 的 committer 中,阿里只占了小部分,其中来自于网易音乐和考拉,微店,韩都衣舍,有赞等公司的开发者也很是活跃。最近有一位印度的开发者,也正式成为了 Dubbo 的 Committer。

生态建设

由于如今生态中,部分实现已经有了重叠,包括后续进来到咱们生态体系里的扩展也会形成一样的扩展或者实现出现重叠,这时候会进行一些优胜劣汰。

Dubbo 和 SpringCloud 关系,部分同窗在选型的时候以为要么选 Dubbo,要么选 SpringCloud,二者互相排斥的。其实不是这样的,这块的详细描述,能够关注公众号:阿里巴巴中间件。里面会有一些文章的描述和分析。

Dubbo 3.0

Dubbo 3.0 的进展,比较受到关注。由于涉及到 Dubbo 和 HSF 整合,以及一些新特性的开放,如 reactive 的引入。可是整个过程是很是漫长的,由于两个产品不可能彻底融合,须要有一些特性存在。并且在完成以后,整个迁移的过程很是巨大。今年上半年,会有一个预览版本,如今很大一部分人力已经投入到 Dubbo 3.0 的研发中。

Service Mesh

Service Mesh,如今还在测试阶段,总体还未达到生产环境的级别。还须要不断优化性能和不断在各个场景中试用

欢迎欢迎学Java的朋友们加入java架构交流: 855835163 群内提供免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)合理利用本身每一分每一秒的时间来学习提高本身,不要再用"没有时间“来掩饰本身思想上的懒惰!趁年轻,使劲拼,给将来的本身一个交代!  

相关文章
相关标签/搜索