【java开发面试篇】之Dubbo常见面试题

778 阅读11分钟

前言: Dubbo微服务项目,应该也算是比较热门成熟的架构了,在此讲讲Dubbo的一些基础面试题,以供大家更深入的了解它,如有错漏,欢迎指正...

随着服务化的进一步发展,服务越来越多,服务之间的调用和依赖关系也越来越复杂,诞生了面向服务的架构体系(SOA), 也因此衍生出了一系列相应的技术,如对服务提供、服务调用、连接处理、通信协议、序列化方式、服务发现、服务路由、日志输出等行为进行封装的服务框架。 就这样为分布式系统的服务治理框架就出现了,Dubbo也就这样产生了。

dubbo总体架构

接口服务层(Service):该层与业务逻辑相关,根据 provider 和 consumer 的业务设计对应的接口和实现
配置层(Config):对外配置接口,以 ServiceConfig 和 ReferenceConfig 为中心
服务代理层(Proxy):服务接口透明代理,生成服务的客户端 Stub 和 服务端的 Skeleton,以 ServiceProxy 为中心,扩展接口为 ProxyFactory
服务注册层(Registry):封装服务地址的注册和发现,以服务 URL 为中心,扩展接口为 RegistryFactory、Registry、RegistryService
路由层(Cluster):封装多个提供者的路由和负载均衡,并桥接注册中心,以Invoker 为中心,扩展接口为 Cluster、Directory、Router和LoadBlancce
监控层(Monitor):RPC调用次数和调用时间监控,以 Statistics 为中心,扩展接口为 MonitorFactory、Monitor和MonitorService
远程调用层(Protocal):封装 RPC 调用,以 Invocation 和 Result 为中心,扩展接口为 Protocal、Invoker和Exporter
信息交换层(Exchange):封装请求响应模式,同步转异步。以 Request 和 Response 为中心,扩展接口为 Exchanger、ExchangeChannel、ExchangeClient和ExchangeServer
网络传输层(Transport):抽象 mina 和 netty 为统一接口,以 Message 为中心,扩展接口为Channel、Transporter、Client、Server和Codec
数据序列化层(Serialize):可复用的一些工具,扩展接口为Serialization、 ObjectInput、ObjectOutput和ThreadPool

总结:这些架构分层,可以理解为都在dubbo的后台管理那边集成。包括集群的控制,监控,路由,各种配置设置等操作

默认使用的是什么通信框架,还有别的选择吗?

默认也推荐使用netty框架,还有mina。

服务调用是阻塞的吗?

默认是阻塞的,可以异步调用,没有返回值的可以这么做。
Dubbo 是基于 NIO 的非阻塞实现并行调用,客户端不需要启动多线程即可完成并行调用多个远程服务,相对多线程开销较小,异步调用会返回一个 Future 对象。

一般使用什么注册中心?还有别的选择吗?

推荐使用 Zookeeper 作为注册中心,还有 Redis、Multicast、Simple 注册中心,但不推荐。

默认使用什么序列化框架,你知道的还有哪些?

推荐使用Hessian序列化,还有Duddo、FastJson、Java自带序列化。

什么是序列化?

在远程调用中,需要把参数和返回值通过网络传输,这个使用就要用到序列化将对象转变成字节流,从一端到另一端之后再反序列化回来变成对象。作用了说了,今天在看文章的时候发现别人贴出效率对比,hessian比java的序列化高出很多。

服务提供者能实现失效踢出是什么原理?

服务失效踢出基于zookeeper的临时节点原理。

服务上线怎么不影响旧版本?

采用多版本开发,不影响旧版本。

如何解决服务调用链过长的问题?

可以结合zipkin实现分布式服务追踪。

说说核心的配置有哪些?

Dubbo 推荐用什么协议?

总的来说,各种协议都是基于rpc的实现,常用的两种:
dubbo协议和hessian协议

1.dubbo协议适合数据量小(推荐)

2.hessian协议可传大文件

注意:dubbo默认使用的通信框架是:netty框架

同一个服务注册多个注册中心吗?可以消费指定注册中心的服务吗?

可以,修改配置即可

画一画服务注册与发现的流程图?

Dubbo 集群容错有几种方案

集群模式配置如:

<dubbo:servicecluster="failsafe"/>

或:

<dubbo:referencecluster="failsafe"/>

Dubbo 服务降级,失败重试怎么做?

可以通过dubbo:reference中设置 mock="return null"。mock 的值也可以修改为 true,然后再跟接口同一个路径下实现一个 Mock 类,命名规则是 “接口名称+Mock” 后缀。然后在 Mock 类里实现自己的降级逻辑

Dubbo 使用过程中都遇到了些什么问题?

在注册中心找不到对应的服务,检查service实现类是否添加了@service注解 无法连接到注册中心,检查配置文件中的对应的测试ip是否正确

Dubbo Monitor 实现原理

dubbo 的monitor是一个监控服务的模块,用来统计服务的调用次数以及调用的健康情况。
Consumer端在发起调用之前会先走filter链;provider端在接收到请求时也是先走filter链,然后才进行真正的业务逻辑处理。
总的来说,monitor本身的原理还是比较简单的,利用filter完成对请求的监控,后续利用定时任务定时采集监控的数据,后续利用MonitorService实现对数据的收集和监听
同时,我们也可以添加自定义的Filter以及特定的MonitorService完成自身特定的需求等

Dubbo 用到哪些设计模式?

Dubbo框架在初始化和通信过程中使用了多种设计模式,可灵活控制类加载、权限控制等功能。

工厂模式:Provider在export服务时,会调用ServiceConfig的export方法。  
装饰器模式 :Dubbo在启动和调用阶段都大量使用了装饰器模式。  
观察者模式 :Dubbo的Provider启动时,需要与注册中心交互,先注册自己的服务,再订阅自己的服务,订阅时,采用了观察者模式,开启一个listener。  
动态代理模式 :Dubbo扩展JDK SPI的类ExtensionLoader的Adaptive实现是典型的动态代理实现。Dubbo需要灵活地控制实现类,即在调用阶段动态地根据参数决定调用哪个实现类,所以采用先生成代理类的方法,能够做到灵活的调用。

Dubbo 支持分布式事务吗?

目前暂时不支持,可与通过 tcc-transaction框架实现
介绍:tcc-transaction是开源的TCC补偿性分布式事务框架
TCC-Transaction 通过 Dubbo 隐式传参的功能,避免自己对业务代码的入侵。

Dubbo可以对结果进行缓存吗?

为了提高数据访问的速度。Dubbo提供了声明式缓存,以减少用户加缓存的工作量

<dubbo:reference cache="true" />

其实比普通的配置文件就多了一个标签 cache="true"

服务上线怎么兼容旧版本?

可以用版本号(version)过渡,多个不同版本的服务注册到注册中心,版本号不同的服务相互间不引用。这个和服务分组的概念有一点类似。

Dubbo必须依赖的包有哪些?

Dubbo 必须依赖 JDK,其他为可选。

Dubbo telnet 命令能做什么?

dubbo服务发布之后,我们可以利用telnet命令进行调试、管理。
Dubbo2.0.5以上版本服务提供端口支持telnet命令
连接服务 telnet localhost 20880 //键入回车进入Dubbo命令模式。
查看服务列表

dubbo>ls
com.test.TestService
dubbo>ls com.test.TestService
create
delete
query

ls (list services and methods)
ls : 显示服务列表。
ls -l : 显示服务详细信息列表。
ls XxxService:显示服务的方法列表。
ls -l XxxService:显示服务的方法详细信息列表。

Dubbo 如何优雅停机?

优雅停机:
服务提供方停止时,先标记为不接收新请求,新请求过来时直接报错,让客户端重试其它机器。然后,检测线程池中的线程是否正在运行,如果有,等待所有线程执行完成,除非超时,则强制关闭。服务消费方停止时,不再发起新的调用请求,所有新的调用在客户端即报错。最后,检测有没有请求的响应还没有返回,等待响应返回,除非超时,则强制关闭。
注意: Dubbo 是通过 JDK 的 ShutdownHook 来完成优雅停机的,线上服务不要轻易的kill -9 PID 等强制关闭指令,是不会执行优雅停机的,只有通过 kill PID 时触发应用的钩子程序,才会执行。

Dubbo 和 Dubbox 之间的区别?

Dubbox 是继 Dubbo 停止维护后,当当网基于 Dubbo 做的一个扩展项目,如加了服务可 Restful 调用,更新了开源组件等。

Dubbo 和 Spring Cloud 的区别?

根据微服务架构在各方面的要素,看看Spring Cloud和Dubbo都提供了哪些支持。

使用Dubbo构建的微服务架构就像组装电脑,各环节我们的选择自由度很高,但是最终结果很有可能因为一条内存质量不行就点不亮了,总是让人不怎么放心,但是如果你是一名高手,那这些都不是问题;而Spring Cloud就像品牌机,在Spring Source的整合下,做了大量的兼容性测试,保证了机器拥有更高的稳定性,但是如果要在使用非原装组件外的东西,就需要对其基础有足够的了解。

dubbo服务调用超时问题解决方案

为什么要用dubbo分组配置?

当一个接口有多种实现时,可以用group区分。因为服务器有限,想在同一个注册中心中,分隔测试和开发环境。

zookeeper和Spring Eureka是什么?

zookeeper提供了分布式锁功能,选主、服务注册与发现、保存元数据信息(作配置文件服务器)等功能
Spring Eureka 从开源转变为闭源,Consul 正在崛起,而 Dubbo 又开始重新更新
是微服务套件中负责服务治理功能的模块。

eureka和zookeeper都可以提供服务注册与发现的功能,请说说两个的区别?

分布式的CAP理论告诉我们“任何一个分布式系统都无法同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance),最多只能同时满足两项。”牺牲强一致性来换取系统的高可用性,系统往往只需要保证“最终一致性”。

zookeeper 是CP原则,强一致性和分区容错性。

eureka 是AP 原则 可用性和分区容错性。

zookeeper当主节点故障时,zk会在剩余节点重新选择主节点,耗时过长,虽然最终能够恢复,但是选取主节点期间会导致服务不可用,这是不能容忍的。

eureka各个节点是平等的,一个节点挂掉,其他节点仍会正常保证服务。

dubbo之令牌验证

防止消费者绕过注册中心访问提供者
在注册中心控制权限,以决定要不要下发令牌给消费者
注册中心可灵活改变授权方式,而不需修改或升级提供者

可以全局设置开启令牌验证

<!--随机token令牌,使用UUID生成-->
<dubbo:provider token="true" />
<!--固定token令牌,相当于密码-->
<dubbo:provider  token="123456" />

也可在服务级别设置:

<!--随机token令牌,使用UUID生成-->
<dubbo:service interface="com.foo.BarService" token="true" />
<!--固定token令牌,相当于密码-->
<dubbo:service interface="com.foo.BarService" token="123456" />

还可在协议级别设置:

<!--随机token令牌,使用UUID生成-->
<dubbo:protocol name="dubbo" token="true" />
<!--固定token令牌,相当于密码-->
<dubbo:protocol name="dubbo" token="123456" />

结语:以往都是看别人的博客进行学习技术,其中不乏有精华博客也有吊儿郎当的CV大法文章,所以决定将自己所学所用所整理的知识分享给大家,主要还是想为了后浪们少走些弯路,多些正能量的博客,如有错漏,欢迎指正,仅希望大家能在我的博客中学到知识,解决到问题,那么就足够了。谢谢大家!(转载请注明原文出处)