Dubbo常问面试题及答案

    技术2022-07-11  86

    Dubbo常问面试题及答案

    1、Dubbo是什么? Dubbo是阿里巴巴开源的基于 Java 的高性能、轻量级的 RPC 分布式服务框架,可以和Spring无缝集成,并且提供了三大核心功能:面向接口的远程方法调用、智能容错和负载均衡、以及服务的自动注册和发现。

    2、为什么要用Dubbo?

    3、Dubbo有哪些角色?

    组件角色说明Provider暴露服务的服务提供方Consumer调用远程服务的服务消费方Registry服务注册与发现的注册中心Monitor统计服务的调用次调和调用时间的监控中心Container服务运行容器

    4、Dubbo的各个角色的工作流程

    服务容器 Container 负责启动,加载,运行服务提供者。服务提供者 Provider 在启动时,向注册中心注册自己提供的服务。服务消费者 Consumer 在启动时,向注册中心订阅自己所需的服务。注册中心 Registry 返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。服务消费者 Consumer,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。服务消费者 Consumer 和提供者 Provider,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心 Monitor。

    5、Dubbo和Spring cloud 有什么不同?

    通信方式不同 Dubbo 使用的是 RPC 通信,而 Spring Cloud 使用的是 HTTP RESTFul 方式。组成部分不同

    6、Dubbo有哪几种集群容错方案,默认是哪种?

    Failover Cluster(默认) 失败自动切换,当出现失败,重试其它服务器。(缺省)通常用于读操作,但重试会带来更长延迟。 可通过retries="2"来设置重试次数(不含第一次)。 <dubbo:service retries="2" cluster="failover"/> 或: <dubbo:reference retries="2" cluster="failover"/> cluster="failover"可以不用写,因为默认就是failover Failfast Cluster 快速失败,当服务消费方调用服务提供者失败后,立即报错,也就是只调用一次。通常这种模式用于非幂等性的写操作。 <dubbo:service cluster="failfast" /> 或: <dubbo:reference cluster="failfast" /> cluster="failfast"和 把cluster="failover"、retries="0"是一样的效果,retries="0"就是不重试 Failsafe Cluster 失败安全,当服务消费者调用服务出现异常时,直接忽略异常。这种模式通常用于写入审计日志等操作。 <dubbo:service cluster="failsafe" /> 或: <dubbo:reference cluster="failsafe" /> Failback Cluster 失败自动恢复,当服务消费端调用服务出现异常后,在后台记录失败的请求,并按照一定的策略后期再进行重试。这种模式通常用于消息通知操作。 <dubbo:service cluster="failback" /> 或: <dubbo:reference cluster="failback" /> Forking Cluster 并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过forks="2"来设置最大并行数。 <dubbo:service cluster=“forking" forks="2"/> 或: <dubbo:reference cluster=“forking" forks="2"/> Broadcast Cluster 广播调用所有提供者,逐个调用,任意一台报错则报错 [2]。通常用于通知所有提供者更新缓存或日志等本地资源信息。

    7、Dubbo有哪几种负载均衡策略,默认是哪种?

    Random LoadBalance:随机策略。按照概率设置权重,比较均匀,并且可以动态调节提供者的权重。RoundRobin LoadBalance:轮循策略。轮循,按公约后的权重设置轮循比率。会存在执行比较慢的服务提供者堆积请求的情况,比如一个机器执行的非常慢,但是机器没有挂(如果挂了,那么当前机器会从 ZooKeeper 的服务列表删除),当很多新的请求到达该机器后,由于之前的请求还没处理完毕,会导致新的请求被堆积,久而久之,所有消费者调用这台机器上的请求都被阻塞。LeastActive LoadBalance:最少活跃调用数。如果每个提供者的活跃数相同,则随机选择一个。在每个服务提供者里面维护着一个活跃数计数器,用来记录当前同时处理请求的个数,也就是并发处理任务的个数。所以如果这个值越小说明当前服务提供者处理的速度很快或者当前机器的负载比较低,所以路由选择时候就选择该活跃度最小的机器。如果一个服务提供者处理速度很慢,由于堆积,那么同时处理的请求就比较多,也就是活跃调用数目越大,这使得慢的提供者收到更少请求,因为越慢的提供者的活跃度越来越大。ConsistentHash LoadBalance 一致性 Hash 策略。一致性 Hash,可以保证相同参数的请求总是发到同一提供者,当某一台提供者挂了时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。

    8、当一个服务接口有多种实现时怎么做?

    当一个接口有多种实现时,可以用 group 属性来分组,服务提供方和消费方都指定同一个 group 即可。

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

    可以用版本号(version)过渡,多个不同版本的服务注册到注册中心,版本号不同的服务相互间不引用。这个和服务分组的概念有一点类似。 10 、Dubbo 支持服务降级吗? 以通过dubbo:reference 中设置 mock=“return null”。mock 的值也可以修改为 true,然后再跟接口同一个路径下实现一个 Mock 类,命名规则是 “接口名称+Mock” 后缀。然后在 Mock 类里实现自己的降级逻辑

    11、Dubbo 如何优雅停机? Dubbo 是通过 JDK 的 ShutdownHook 来完成优雅停机的,所以如果使用 kill -9 PID 等强制关闭指令,是不会执行优雅停机的,只有通过 kill PID 时,才会执行。

    12、Dubbo 和 Dubbox 之间的区别? Dubbox 是继 Dubbo 停止维护后,当当网基于 Dubbo 做的一个扩展项目,如加了服务可 Restful 调用,更新了开源组件等。 13、Dubbo 可以对结果进行缓存吗? 为了提高数据访问的速度。Dubbo提供了声明式缓存,以减少用户加缓存的工作量

    <dubbo:reference cache="true" />

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

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

    15、Dubbo必须依赖的包有哪些? Dubbo 必须依赖 JDK,其他为可选。

    16、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:显示服务的方法详细信息列表。 17、Dubbo 支持分布式事务吗? 目前暂时不支持,可与通过 tcc-transaction框架实现 介绍:tcc-transaction是开源的TCC补偿性分布式事务框架 Git地址:https://github.com/changmingxie/tcc-transaction TCC-Transaction 通过 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

    默认使用的是什么通信框架,还有别的选择吗? 默认也推荐使用netty框架,还有mina。

    服务调用是阻塞的吗? 默认是阻塞的,可以异步调用,没有返回值的可以这么做。

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

    一般使用什么注册中心?还有别的选择吗? 推荐使用 Zookeeper 作为注册中心,还有 Redis、Multicast、Simple 注册中心,但不推荐。

    默认使用什么序列化框架,你知道的还有哪些? 推荐使用Hessian序列化,还有Duddo、FastJson、Java自带序列化。

    服务提供者能实现失效踢出是什么原理? 服务失效踢出基于zookeeper的临时节点原理。

    如何解决服务调用链过长的问题? 可以结合zipkin实现分布式服务追踪。

    Dubbo 都有哪些协议?推荐使用哪种?其它协议的使用场景是什么? dubbo://(推荐) rmi:// hessian:// http:// webservice:// thrift:// memcached:// redis:// rest://

    Dubbo的完整调用链路

    17、线程模型 需要通过不同的派发策略和不同的线程池配置的组合来应对不同的场景:

    <dubbo:protocol name="dubbo" dispatcher="all" threadpool="fixed" threads="100" />

    Dispatcher

    all 所有消息都派发到线程池,包括请求,响应,连接事件,断开事件,心跳等。direct 所有消息都不派发到线程池,全部在 IO 线程上直接执行。message 只有请求响应消息派发到线程池,其它连接断开事件,心跳等消息,直接在 IO 线程上执行。execution 只请求消息派发到线程池,不含响应,响应和其它连接断开事件,心跳等消息,直接在 IO 线程上执行。connection 在 IO 线程上,将连接断开事件放入队列,有序逐个执行,其它消息派发到线程池。

    ThreadPool

    fixed 固定大小线程池,启动时建立线程,不关闭,一直持有。(缺省)cached 缓存线程池,空闲一分钟自动删除,需要时重建。limited 可伸缩线程池,但池中的线程数只会增长不会收缩。只增长不收缩的目的是为了避免收缩时突然来了大流量引起的性能问题。eager 优先创建Worker线程池。在任务数量大于corePoolSize但是小 maximumPoolSize时,优先创建Worker来处理任务。当任务数量大 maximumPoolSize时,将任务放入阻塞队列中。阻塞队列充满时抛 RejectedExecutionException。(相比于cached:cached在任务数量超过maximumPoolSize时直接抛出异常而不是将任务放入阻塞队列)
    Processed: 0.011, SQL: 9