30道Dubbo面试题及答案

Q1:服务调用超时问题怎么解决
A:
消费者调用服务超时会引起服务降级的发生,即从发出调用请求到获取到提供者的响应结果
这个时间超出了设定的时限。默认服务调用超时时限为 1 秒。可以在消费者端与提供者端设
置超时时限来解决。
总的来说还是要设计好业务代码来减少调用时长,设置准确 RPC 调用的超时时间才能更好
的解决这个问题。
Q2:Dubbo 支持哪些序列化方式?
A:
默认使用 Hessian 序列化,还有 Duddo、FastJson、Java 自带序列化。
Q3:Dubbo 和 SpringCloud 的关系?
A:
Dubbo 是 SOA 时代的产物,它的关注点主要在于服务的调用,流量分发、流量监控和熔断。
而 SpringCloud 诞生于微服务架构时代,考虑的是微服务治理的方方面面,另外由于依托
了 Spirng、SpirngBoot 的优势之上,两个框架在开始目标就不一致,Dubbo 定位服务治理、
SpirngCloud 是一个生态。
Q4:Dubbo 的架构设计?
A:
Dubbo 框架设计一共划分了 10 个层 :
服务接口层(Service):该层是与实际业务逻辑相关的,根据服务
提供方和服务消费方的业务设计对应的接口和实现。
配置层(Config):对外配置接口,以 ServiceConfig 和 ReferenceConfig 为中心。
服务代理层(Proxy):服务接口透明代理,生成服务的客户端 Stub 和服务器端
Skeleton。
服务注册层(Registry):封装服务地址的注册与发现,以服务 URL 为中心。
集群层(Cluster):封装多个提供者的路由及负载均衡,并桥接注册中心,以Invoker为中心。
监控层(Monitor):RPC 调用次数和调用时间监控。
远程调用层(Protocol):封将 RPC 调用,以 Invocation 和 Result 为中心,扩展接口为
Protocol、Invoker 和 Exporter。
信息交换层(Exchange):封装请求响应模式,同步转异步,以Request和Response为中心。
网络传输层(Transport):抽象 mina 和 netty 为统一接口,以 Message 为中心。
Q5:Dubbo 的默认集群容错方案?
A:
FailoverCluster
Q6 : Dubbo 使用的是什么通信框架 ?
A:
默认使用 NIO Netty 框架
Q7:Dubbo 的主要应用场景?
A:
透明化的远程方法调用,就像调用本地方法一样调用远程方法,只需简单配置,没有任何
API侵入。软负载均衡及容错机制,可在内网替代F5等硬件负载均衡器,降低成本,减少单点。
服务自动注册与发现,不再需要写死服务提供方地址,注册中心基于接口名查询服务提供者
的 IP 地址,并且能够平滑添加或删除服务提供者。
Q8:Dubbo 服务注册与发现的流程?
A:
流程说明:
Provider( 提供者 ) 绑定指定端口并启动服务·指供者连接注册中心,并发本机 IP、端口、应
用信息和提供服务信息发送至注册中心存储
Consumer( 消费者),连接注册中心,并发送应用信息、所求服务信息至注册中心·注册中
心根据消费者所求服务信息匹配对应的提供者列表发送至 Consumer 应用缓存。
Consumer 在发起远程调用时基于缓存的消费者列表择其一发起调用。
Provider 状态变更会实时通知注册中心、在由注册中心实时推送至
Consumer
设计的原因:
Consumer 与 Provider 解偶,双方都可以横向增减节点数。
注册中心对本身可做对等集群,可动态增减节点,并且任意一台宕掉后,将自动切换到另一
台去中心化,双方不直接依懒注册中心,即使注册中心全部宕机短时间内也不会影响服务的
调用服务提供者无状态,任意一台宕掉后,不影响使用
Q9:Dubbo 的负载均衡是如何实现的?
A:
无论是 Dubbo 还是 Spring Cloud,负载均衡原理都是相同的。消费者从注册中心中获取到
当前其要消费服务的所有提供者,然后对这些提供者按照指定的负载均衡策略获取到其中的
一个提供者,然后进行调用。当调用失败时,会再按照容错机制进行处理。
不同的是,Dubbo 中还可以在负载均衡之前先根据设定好的路由规则对所有可用提供者进
行路由,从中筛选掉一部分不符合规则的提供者,对剩余提供者再进行负载均衡。
Dubbo 中默认支持四种负载均衡策略:加权随机策略、加权最小活跃度调度策略、双权重
轮询策略,及一致性 hash 策略。
Spring Cloud(H 版 ) 一般使用 Ribbon 实现负载均衡,其默认支持五种负载均衡策略:轮询
策略、随机策略、重试策略、最可用策略,及可用过滤策略。
Q10:Dubbo 的四大组件
A:
1、Provider:服务提供者。
2、Consumer:服务消费者。
3、Registry:服务注册与发现的中心,提供目录服务,亦称为服务注册中心
4、Monitor:统计服务的调用次数、调用时间等信息的日志服务,并可以对服务设置权限、
降级处理等,称为服务管控中心
Q11:Dubbo 在安全机制方面是如何解决的
A:
Dubbo 通过 Token 令牌防止用户绕过注册中心直连,然后在注册中心上管理授权。Dubbo
还提供服务黑白名单,来控制服务所允许的调用方。
Q12:Dubbo 和 SpringCloud 中的 OpenFeign 组件的区别?
A:
最大的区别:Dubbo 底层是使用 Netty 这样的 NIO 框架,是基于 TCP 协议传输的,配合以
Hession 序列化完成 RPC 通信。
而 SpringCloud 是基于 Http 协议 +Rest 接口调用远程过程的通信,相对来说,Http 请求
会有更大的报文,占的带宽也会更多。但是 REST 相比 RPC 更为灵活。
Q13:Dubbo 支持哪些协议,每种协议的应用场景,优缺点?
A:
dubbo 协议 :
Dubbo 默认传输协议
连接个数:单连接
连接方式:长连接
协议:TCP
传输方式:NIO 异步传输
适用范围:传入传出参数数据包较小(建议小于 100K),消费者比提供者个数多,单一 消
费者无法压满提供者,尽量不要用 dubbo 协议传输大文件或超大字符串。
rmi:采用 JDK 标准的 rmi 协议实现,传输参数和返回参数对象需要实现 Serializable 接口,
使用 java 标准序列化机制,使用阻塞式短连接,传输数据包大小混合,消费者和提供者个
数差不多,可传文件,传输协议 TCP。多个短连接,TCP 协议传输,同步传输,适用常规的
远程服务调用和 rmi 互操作。在依赖低版本的 Common-Collections 包,java 序列化存在
安全漏洞;
webservice:基于 WebService 的远程调用协议,集成 CXF 实现,提供和原生 WebService
的互操作。多个短连接,基于 HTTP 传输,同步传输,适用系统集成和跨语言调用;
http:基于 Http 表单提交的远程调用协议,使用 Spring 的 HttpInvoke 实现。多个短连接,
传输协议 HTTP,传入参数大小混合,提供者个数多于消费者,需要给应用程序和浏览器 JS
调用;hessian:集成 Hessian 服务,基于 HTTP 通讯,采用 Servlet 暴露服务,Dubbo 内
嵌 Jetty 作为服务器时默认实现,提供与 Hession 服务互操作。多个短连接,同步 HTTP 传
输,Hessian 序列化,传入参数较大,提供者大于消费者,提供者压力较大,可传文件;
memcache:基于 memcached 实现的 RPC 协议
redis:基于 redis 实现的 RPC 协议
Q14:Dubbo 的核心功能有哪些?
A:
主要就是如下 3 个核心功能:
Remoting:网络通信框架,提供对多种 NIO 框架抽象封装,包括“同步转异步”和“请求 -
响应”模式的信息交换方式。
Cluster:服务框架,提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负
载均衡,失败容错,地址路由,动态配置等集群支持。
Registry:服务注册,基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使
地址透明,使服务提供方可以平滑增加或减少机器。
Q15:Dubbo 的注册中心集群挂掉,发布者和订阅者之间还能通信
么?
A:
可以的,启动 dubbo 时,消费者会从 zookeeper 拉取注册的生产者的地址接口等数据,缓
存在本地。每次调用时,按照本地存储的地址进行调用。
Q16:Dubbo 的集群容错方案有哪些?
A:
FailoverCluster:失败自动切换,当出现失败,重试其它服务器。通常用于读操作,但重试
会带来更长延迟。
FailfastCluster:快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,
比如新增记录。FailsafeCluster:失败安全,出现异常时,直接忽略。通常用于写入审计日
志等操作。
FailbackCluster:失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。
ForkingCluster:并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的
读操作,但需要浪费更多服务资源。可通过 forks=”2″来设置最大并行数。
BroadcastCluster:广播调用所有提供者,逐个调用,任意一台报错则报错。通常用于通知
所有提供者更新缓存或日志等本地资源信
Q17:Dubbo 集群的负载均衡有哪些策略
A:
Dubbo 提供了常见的集群策略实现,并预扩展点予以自行实现。
A、 random :随机算法,是 Dubbo 默认的负载均衡算法。存在服务堆积问题。
B、 roundrobin :轮询算法。按照设定好的权重依次进行调度。
C、 leastactive :最少活跃度调度算法。即被调度的次数越少,其优选级就越高,被调度到
的机率就越高。
D、 consistenthash :一致性 hash 算法。对于相同参数的请求,
其会被路由到相同的提供者。
Q18:为什么需要服务治理?
A:
服务治理是主要针对分布式服务框架的微服务,处理服务调用之间的关系、服务发布和发现、
故障监控与处理,服务的参数配置、服务降级和熔断、服务使用率监控等。
原因:
过多的服务 URL 配置困难
负载均衡分配节点压力过大的情况下也需要部署集群
服务依赖混乱,启动顺序不清晰
过多服务导致性能指标分析难度较大,需要监控
故障定位与排查难度较大
Q19:Dubbo 超时时间怎样设置?
A:
Dubbo 超时时间设置有两种方式:
服务提供者端设置超时时间,在 Dubbo 的用户文档中,推荐如果能在服务端多配置就尽量
多配置,因为服务提供者比消费者更清楚自己提供的服务特性。
服务消费者端设置超时时间,如果在消费者端设置了超时时间,以消费者端为主,即优先级
更高。因为服务调用方设置超时时间控制性更灵活。如果消费方超时,服务端线程不会定制,
会产生警告。
Q20:Dubbo 框架源码最重要的设计原则是什么?从架构设计角度
谈一下你对这个设计原则的理解。
A:
Dubbo 在设计时具有两大设计原则:
“微内核 + 插件”的设计模式。内核只负责组装插件(扩展点),Dubbo 的功能都是由插
件实现的,也就是 Dubbo 的所有功能点都可被用户自定义扩展类所替换。Dubbo 的高扩展
性、开放性在这里被充分体现。
采用 URL 作为配置信息的统一格式,所有扩展点都通过传递 URL 携带配置信息。简单来说
就是,在 Dubbo 中,所有重要资源都是以 URL 的形式来描述的。
Q21:为什么 Dubbo 使用 URL,而不使用 JSON,使用 URL 的好
处是什么?

A:
关于这个问题,官方是没有相关说明的,下面我谈两点我个人的看法:
首先,Dubbo 是将 URL 作为公共契约出现的,即希望所有扩展点都要遵守的约定。既然是
约定,那么可以这样约定,也可以那样约定。只要统一就行。所以,在 Dubbo 创建之初,
也许当时若采用了 JSON 作为这个约定也是未偿不可的。
其次,单从 JSON 与 URL 相比而言,都是一种简洁的数据存储格式。但在简洁的同时,
URL与Dubbo应用场景的契合度更高些。因为Dubbo中URL的所有应用场景都与通信有关,
都会涉及到通信协议、通信主机、端口号、业务接口等信息。其语义性要强于 JSON,且对
于这些数据就无需再给出相应的 key 了,会使传输的数据量更小。
Q22:请简述一下 Dubbo 四大组件间的关系。
A:
Dubbo 的四大组件为:Consuer、Provider、Registry 与 Monitor。它们间的关系可以描述
为如下几个
过程:
start:Dubbo 服务启动,Spring 容器首先会创建服务提供者。
register:服务提供者创建好后,马上会注册到服务注册中心 Registry,这个注册过程称
为服务暴露。服务暴露的本质是将服务名称(接口)与服务提供者主机写入到注册中心
Registry 的服务映射表中。注册中心充当着“DNS 域名服务器”的角色。
subscribe:服务消费者启动后,首先会向服务注册中心订阅相关服务。
notify:消费者可能订阅的服务在注册中心还没有相应的提供者。当相应的提供者在注册中
心注册后,注册中心会马上通知订阅该服务的消费者。但消费者在订阅了指定服务后,在没
有收到注册中心的通知之前是不会被阻塞的,而是可以继续订阅其它服务。
invoke:消费者以同步或异步的方式调用提供者提供的请求。消费者通过远程注册中心获取
到提供者列表,然后消费者会基于负载均衡算法选一台提供者处理消费者的请求。
count:每个消费者对各个服务的累计调用次数、调用时间;每个提供者被消费者调用的累
计次数和时间,消费者与调用者都会定时发送到监控中心,由监控中心记录。这些统计数据
可以在 Dubbo 的可视化界面看到。
Q23:什么是 SPI ?请简单描述一下 SPI 要解决的问题。
A:
SPI,Service Provider Interface,服务提供者接口,是一种服务发现机制。其主要是解决
面向抽象编程中上层对下层接口实现类的依赖问题,可以实现这两层间的解耦合。
Q24:JDK 的 SPI 机制存在什么问题?
A:
JDK 的 SPI 机制将所有配置文件中的实现类全部实例化,无论是否能够用到,浪费了宝贵的
系统资源。
Q25:简述 Dubbo 的 Wrapper 机制
A:
Wrapper 机制,即扩展类的包装机制。就是对扩展类中的 SPI 接口方法进行增强,进行包装,
是 AOP 思想的体现,是 Wrapper 设计模式的应用。一个 SPI 可以包含多个 Wrapper,即
可以通过多个 Wrapper 对同一个扩展类进行增强,增强不出现的功能。Wrapper 机制不是
通过注解实现的,而是通过一套 Wrapper 规范实现的。
Q26:Dubbo 的 Wrapper 类是否属于扩展类?
A:
wrapper 类仅仅是对现有的扩展类功能上的增强,并不是一个独立的扩展类,所以其不属于
扩展类范畴。
Q27:简述 Dubbo 的 Active 机制
A:
Activate 机制,即扩展类的激活机制。通过指定的条件来实现一次激活多个扩展类的目的。
激活机制没有增强扩展类,也没有增加扩展类,其仅仅是为原有的扩展类添加了更多的识别
标签,而不像之前的,每个扩展类仅有一个“功能性扩展名”识别标签。其是通过 @Active
注解实现的。
Q28:Dubbo 的 Activate 类是否属于扩展类?
A:
Activate 机制仅用于为扩展类添加激活标识的,其是通过在扩展类上添加 @Activate 注解来
实现的,所以 Activate 类本身就是扩展类。
Q29:简述 Dubbo 中配置中心与注册中心的关系
A:
Dubbo 中的注册中心是用于完成服务发现的,而配置中心是用于完成配置信息的统一管理
的。若没有专门设置配置中心,系统会默认将注册中心服务器作为配置中心服务器。
Q30:Dubbo 内核工作原理的四个构成机制间的关系是怎样的?或
者说,一个扩展类实例获取过程是怎样的?

A:
获取一个扩展类实例,一般需要经过这样几个环节:
获取到该SPI接口的ExtensionLoader。而这个获取的过程会将该SPI接口的所有扩展类(四
类)加载并缓存。
通过 extensionLoader 获取到其自适应实例。通常 SPI 接口的自适应实例都是由 Adaptive
方法自动生成的,所以需要对这个自动生成的 Adaptive 类进行动态编译。
在通过自适应实例调用自适应的业务方法时,才会获取到其真正需要的扩展类实例。所以说,
一个扩展类实例一般情况下是在调用自适应方法时才创建。
在获取这个真正的扩展类实例时,首先会根据要获取的扩展类实例的“功能性扩展名”,从
扩展类缓存中找到其对应的扩展类,然后调用其无参构造器,创建扩展类实例 instance。
通过 injectExtension(instance) 方法,调用 instance 实例的 setter 完成初始化。
遍历所有该 SPI 的 Wrapper,逐层包装这个 setter 过的 instance。此时的这个 instance,
即 wrapper 实例就是我们需要获取的扩展类实例。

你可能感兴趣的:(学习笔记)