35岁程序员面试:Dubbo致命一击20问

2022-09-23 17:29:38 浏览数 (1)

Dubbo是阿里巴巴开源的高性能和轻量级的服务治理框架,它提供了六大核心能力:面向接口代理的高性能RPC调用、智能容错和负载均衡、服务自动注册与发现、高度可扩展能力、运行期间流量调度和可视化的服务服务治理与运维。

核心能力主要描述如下:

  • 什么是面向接口代理的高性能RPC调用呢?它是指Dubbo提供高性能的基于代理的远程调用能力,服务以接口为粒度,为开发者屏蔽远程调用底层细节;
  • 什么是智能负载均衡呢?它是指Dubbo内置了多种负载均衡策略,并能够智能的感知下游服务节点的健康状况,因此可以显著的减少调用延迟,从而提高系统吞吐量;
  • 什么是服务自动注册与发现呢?它是指Dubbo支持多种注册中心服务,支持服务实例动态的上下线;
  • 什么是高度可扩展能力呢?它是指Dubbo遵循内核 插件的设计原则(SPI设计模式),所有的核心能力比如Protocol、Transport、Serialization本设计为扩展点;
  • 什么是运行期间流量调度呢?它是指Dubbo通过内置条件、脚本等路由策略,通过配置不同的路由规则,轻松实现灰度发布,同机房优先等功能;
  • 什么是可视化的服务治理与运维呢?它是指Dubbo提供丰富服务治理、运维工具,并可以实时的查看服务元数据、服务健康状态及调用统计,实时的下发路由策略、并调整配置参数。

好吧,我们了解了Dubbo的这些功能特性之后,就可以开始Dubbo致命一击20问了。

第一问,Dubbo支持多注册中心吗?

Dubbo支持同一服务向多注册中心同时注册,或者不同服务分别注册到不同的注册中心上,甚至可以同时引用注册在不同注册中心上的同名服务。另外,注册中心是支持自定义扩展的。

第二问,Dubbo服务如果开启服务调用重试,默认是几次?

首先,Dubbo是支持服务调用重试的,其次,Dubbo默认支持重试2次(加上正常的调用一次,总共会发起3次RPC请求),最后可以用参数“retries”来设置。

注意在版本Dubbo3.0之前,如果开启了重试,但是没有设置重试次数,默认是2次,但是在Dubbo3.0及之后的版本,默认次数为-1,也就是不重试。

第三问,什么是Dubbo服务启动时检查?

Dubbo支持在启动时检查依赖服务是否可用。

Dubbo默认会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止Spring容器的初始化,以便上线之前能够预判服务故障,用参数“check=true”来开启服务启动时检查。

如果Spring容器是懒加载的或者通过API编程延迟引用依赖服务的,需要关闭check,否则依赖服务临时不可用,会直接抛出异常。如果“check=false”,Dubbo总会返回引用,当服务恢复时,服务订阅者能够自动的连上服务提供者。

第四问,什么是服务分组?

Dubbo使用服务分组来区分服务接口的不同实现,也就是说当一个接口有多种实现时,可以用Group区分。

第五问,什么是多版本?

Dubbo支持为同一个服务配置多个版本,也就是说当一个接口实现,出现不兼容升级时,可以用版本号过渡,版本号不同的服务相互间不引用。

可以按照以下的步骤进行业务接口版本的迁移:

  • 在低负载时间段,先升级一半服务提供者的版本号为新的版本;
  • 再降所有的消费者升到到新的版本;
  • 然后将剩下的一般服务提供者升到新的版本。

第六问,Dubbo支持多协议吗?

Dubbo是支持多协议的,开发者可以在Dubbo中配置多协议,并在不同服务上支持不同协议或者同一服务上同时支持多种协议。

第七问,Dubbo支持只订阅不注册吗?

Dubbo是支持只订阅不注册的,为了方便开发测试,经常会下线下共用一个注册中心,如果一个正在开发中的服务提供者注册,可能会影响其它的消费者不能正常运行。

比如开发人员在开发服开发订单服务中的订单接口,但是开发人员连接的是测试环境的注册中心,如果这个正在开发的订单服务注册到了注册中心中,那么测试环境中依赖订单服务的交易服务,会通过负载均衡,将订阅的流量路由到开发人员正在开发的订单服务上,但实际上这个开发中的订单服务的功能是不稳定的和可用性极低(开发人员会经常重启)。

第八问,Dubbo支持直连服务提供者吗?

Dubbo是支持直连服务提供者的,也就是说服务订阅者可以绕过注册中心,采用点对点的直连方式。在开发及测试环境中,经常需要绕开注册中心,只测试指定服务提供者,这个时候可能需要点对点直连,将以服务接口为单位,忽略注册中心的提供者列表。

第九问,Dubbo的线程模型是什么?

软件开发人员可以配置Dubbo中的线程模型。

如果业务能够快速的完成,并不会发起新的I/O请求,比如只是在内存中计算(也就是CPU密集型),则直接在I/O线程线程上处理更快,减少了线程池的调度。

但如果事件耗时很多或者需要发起新的I/O请求,比如需要查询数据库,则必须派发到线程池,否则会阻塞I/O线程,将导致不能当前接口不能接收其它请求。

如果用I/O线程处理事件,又在事件处理过程中发起新的I/O请求,比如在连接事件中发起登录请求,会报“可能引发死锁”的异常,但不会真会死锁。

因此,需要通过不同的派发策略和不同的线程池配置的组合来应对不同的业务场景。

Dispatcher(派发策略类型)主要包括:

  • all

所有消息都派发到线程池,包括请求、响应、连接事件、断开事件和心跳等。

  • direct

所有消息都不派发到线程池,全部在I/O线程上直接执行。

  • message

只有请求响应消息派发到线程池,其它连接断开事件,心跳等消息,直接在 IO 线程上执行。

  • Execution

只有请求消息派发到线程池,不含响应,响应和其它连接断开事件,心跳等消息,直接在 IO 线程上执行。

  • connection

在 IO 线程上,将连接断开事件放入队列,有序逐个执行,其它消息派发到线程池。

ThreadPool(线程池类别)主要包括:

  • fixed

固定大小线程池,启动时建立线程,不关闭,一直持有。(缺省)

  • cached

缓存线程池,空闲一分钟自动删除,需要时重建。

  • limited

可伸缩线程池,但池中的线程数只会增长不会收缩。只增长不收缩的目的是为了避免收缩时突然来了大流量引起的性能问题。

  • eager

优先创建Worker线程池。在任务数量大于corePoolSize但是小于maximumPoolSize时,优先创建Worker线程池来处理任务。当任务数量大于maximumPoolSize时,将任务放入阻塞队列中。阻塞队列充满时抛出RejectedExecutionException。(相比于“cached派发策略”,“eager 派发策略”在任务数量超过maximumPoolSize时直接抛出异常而不是将任务放入阻塞队列)。

第十问,Dubbo支持静态服务吗?

Dubbo支持将服务标识为非动态管理模式,主要场景是软件开发人员希望人工管理服务提供者的上线和下线,因此需要将服务提供者标识为非动态管理模式,用参数“dynamic=false”来设置。

第十一问,什么是Dubbo负载均衡?

具体实现上,Dubbo 提供的是客户端负载均衡,即由 Consumer 通过负载均衡算法得出需要将请求提交到哪个 Provider 实例。

Dubbo支持的负载均衡算法主要包括如下几种:

  • RandomLoadBalance,它是加权随机算法,是Dubbo负载均衡默认支持的算法,Provider 实例的权重相同;
  • RoundRobinLoadBalance,它是加权轮询,主要是借鉴了Nginx的平滑加权轮询算法,默认Provider 实例的权重相同;
  • LeastActiveLoadBalance,它是最少活跃优先 加权随机算法,主要的特性是能者多劳,也就是Provider 实例越活跃,它的流量就会越多;
  • ShortestResponseLoadBalance,它是最短响应优先 加权随机算法,主要特性是Provider 实例的性能越高,响应时间越短,则流量就会越多;
  • ConsistentHashLoadBalance,它是一致性Hash算法,主要是确定的入参,确定的Provider 实例,适用于有状态的服务。

第十二问,Dubbo支持哪些集群容错模式?

在Dubbo中,如果集群调用失败时,Dubbo提供了如下几种集群容错模式:

  • Failover Cluster

也叫失败自动切换,当出现失败,重试其它服务器。通常用于读操作,但重试会带来更长延迟。可通过 retries="2" 来设置重试次数(不含第一次)。

  • Failfast Cluster

也叫快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,比如新增记录。

  • Failsafe Cluster

也叫失败安全,出现异常时,直接忽略。通常用于写入审计日志等操作。

  • Failback Cluster

也叫失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。

  • Forking Cluster

也叫并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过 forks="2" 来设置最大并行数。

  • Broadcast Cluster

也叫广播调用所有提供者,逐个调用,任意一台报错则报错。通常用于通知所有提供者更新缓存或日志等本地资源信息。

第十三问,Dubbo支持配置中心吗?

Dubbo是支持配置中心的,它主要支持Nacos、Apollo和ZooKeeper,是可以通过SPI扩展的。

第十四问,Dubbo支持哪些注册中心?

Dubbo支持多种注册中心,它主要支持DNS、Kubernetes、Multicast、Multiple、Nacos、Xds和ZooKeeper,是可以通过SPI扩展的。

第十五问,Dubbo支持哪些RPC框架?

Dubbo支持多种RPC框架,它主要支持HTTP、Netty、ZooKeeper,是可以通过SPI扩展的。

第十六问,Dubbo支持哪些RPC协议?

Dubbo支持多种RPC协议,它主要支持Dubbo、gRPC、Rest和Injvm,是可以通过SPI扩展的。

第十七问,Dubbo支持哪些序列化框架?

Dubbo支持多种序列化框架,它主要支持Hessian和JDK自带的序列化框架,是可以通过SPI扩展的。

第十八问,Dubbo3.0新特性,你了解多少?

(1)全新服务发现模型

相比于 2.x 版本中的基于接口粒度的服务发现机制,3.x 引入了全新的基于应用粒度的服务发现机制, 新模型带来两方面的巨大优势:

  • 进一步提升了 Dubbo3 在大规模集群实践中的性能与稳定性。新模型可大幅提高系统资源利用率,降低 Dubbo 地址的单机内存消耗(50%),降低注册中心集群的存储与推送压力(90%), Dubbo 可支持集群规模步入百万实例层次。
  • 打通与其他异构微服务体系的地址互发现障碍。新模型使得 Dubbo3 能实现与异构微服务体系如Spring Cloud、Kubernetes Service、gRPC 等,在地址发现层面的互通, 为连通 Dubbo 与其他微服务体系提供可行方案。

在 Dubbo3 前期版本将会同时提供对两套地址发现模型的支持,以最大程度保证业务升级的兼容性。

(2)全新的 RPC 通信协议

定义了全新的 RPC 通信协议 – Triple,一句话概括 Triple:它是基于 HTTP/2 上构建的 RPC 协议,完全兼容 gRPC,并在此基础上扩展出了更丰富的语义。使用 Triple 协议,开发者将获得以下能力:

  • 更容易到适配网关、Mesh架构,Triple 协议让 Dubbo 更方便的与各种网关、Sidecar 组件配合工作。
  • 多语言友好,推荐配合 Protobuf 使用 Triple 协议,使用 IDL 定义服务,使用 Protobuf 编码业务数据。
  • 流式通信支持,Triple 协议支持 Request Stream、Response Stream、Bi-direction Stream。

(3)云原生

Dubbo3 构建的业务应用可直接部署在 VM、Container、Kubernetes 等平台,Dubbo3 很好的解决了 Dubbo 服务与调度平台之间的生命周期对齐,Dubbo 服务发现地址 与容器平台绑定的问题。

在服务发现层面,Dubbo3 支持与 Kubernetes Native Service 的融合,目前限于 Headless Service。

Dubbo3 规划了两种形态的 Service Mesh 方案,在不同的业务场景、不同的迁移阶段、不同的基础设施保障情况下,Dubbo 都会有 Mesh 方案可供选择, 而这进一步的都可以通过统一的控制面进行治理:

  • 经典的基于 Sidecar 的 Service Mesh;
  • 无 Sidecar 的 Proxyless Mesh。

软件开发人员在 Dubbo2 中熟知的路由规则,在 3.x 中将被一套统一的流量治理规则取代,这套统一流量规则将覆盖未来 Dubbo3 的 Service Mesh、SDK 等多种部署形态, 实现对整套微服务体系的治理。

(4)全面的性能提升

对比 2.x 版本,Dubbo3 版本

  • 服务发现资源利用率显著提升:
  1. 对比接口级服务发现,单机常驻内存下降 50%,地址变更期 GC 消耗下降一个数量级 (百次 -> 十次)。
  2. 对比应用级服务发现,单机常驻内存下降 75%,GC 次数趋零。
  • Dubbo 协议性能持平,Triple 协议在网关、Stream吞吐量方面更具优势:
  1. Dubbo协议 (3.0 vs 2.x),3.0 实现较 2.x 总体 qps rt 持平,略有提升。
  2. Triple协议 vs Dubbo协议,直连调用场景 Triple 性能并无优势,其优势在网关、Stream调用场景。

第十九问,有看过Dubbo的源码吗?

从Dubbo分层的角度去阐述Dubbo源码的结构,体现出源码的架构思想,当然人都不可能全部记住源码的细节,一定要关注Dubbo的源码思想。

第二十问,有在业务项目中应用过Dubbo吗?

从实战的角度去阐述使用Dubbo的一些坑,最好是结合业务场景。比如最常见的场景是用了Dubbo的哪些特性,解决了业务开发过程中的哪些问题。

列觉一个简单的例子,我使用了Dubbo的异步调用的功能解决了订单支付慢的性能问题,好吧这个就可以展开了。

本公众号后续文章会用尽量少的文字来带着大家拓展新的技术,言简意赅是文章的特色,要让读者不能白读文章。

知识输出是笔者的初衷,借助知识输出,能够认识更多的牛人,能够和牛人沟通,也是自己技术提升的一个机会。


下一期:几张图搞定Spring Cloud Alibaba配置中心的架构原理


0 人点赞