Dubbo

Dubbo相关的知识及常见问题:)

各种知识点总结

常见面试题

  1. 什么是Dubbo?

    是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。

    面向服务的架构(SOA)是一个组件模型,它将应用程序的不同功能单元(称为服务)进行拆分,并通过这些服务之间定义良好的接口和协议联系起来。接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台、操作系统和编程语言。这使得构件在各种各样的系统中的服务可以以一种统一和通用的方式进行交互。

  2. 什么是RPC?

    RPC工作时序图

    Remote Procedure Call 是一种远程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。

    例如,A,B服务分别部署在两台不同的机器上,如何解决服务A调用服务B中的某个方法的问题,HTTP请求较慢,RPC应运而生。

  3. 为什么使用Dubbo?

    • 负载均衡:同一个服务部署在不同的机器时该调用那一台机器上的服务;

    • 服务调用链路生成:随着系统的发展,服务越来越多,服务间依赖关系变得错踪复杂,Dubbo可以解决服务之间互相是如何调用的;

    • 服务访问压力以及时长统计、资源调度和治理:基于访问压力实时管理集群容量,提高集群利用率;

    • 服务降级:某个服务挂掉之后调用备用服务;

  4. Dubbo的架构

    Dubbo架构

    Provider:暴露服务的服务提供方;

    Consumer:调用远程服务的服务消费方;

    Registry:服务注册与发现的注册中心;

    Monitor:统计服务的调用次数和调用时间的监控中心;

    Container:服务运行容器;

    • 调用关系

      服务容器负责启动,加载,运行服务提供者;

      服务提供者在启动时,向注册中心注册自己提供的服务;

      服务消费者在启动时,向注册中心订阅自己所需的服务;

      注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者;

      服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用;

      服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心;

    重要知识点总结:

    注册中心负责服务地址的注册与查找,相当于目录服务,服务提供者和消费者只在启动时与注册中心交互,注册中心不转发请求,压力较小;

    监控中心负责统计各服务调用次数,调用时间等,统计先在内存汇总后每分钟一次发送到监控中心服务器,并以报表展示;

    注册中心,服务提供者,服务消费者三者之间均为长连接,监控中心除外;

    注册中心通过长连接感知服务提供者的存在,服务提供者宕机,注册中心将立即推送事件通知消费者;

    注册中心和监控中心全部宕机,不影响已运行的提供者和消费者,消费者在本地缓存了提供者列表;

    注册中心和监控中心都是可选的,服务消费者可以直连服务提供者;

    服务提供者无状态,任意一台宕掉后,不影响使用;

    服务提供者全部宕掉后,服务消费者应用将无法使用,并无限次重连等待服务提供者恢复;

  5. Dubbo工作原理

    图中从下至上分为十层,各层均为单向依赖,右边的黑色箭头代表层之间的依赖关系,每一层都可以剥离上层被复用,其中,Service 和 Config 层为 API,其它各层均为 SPI。

    各层说明:

    • 第一层:service层,接口层,给服务提供者和消费者来实现的;
    • 第二层:config层,配置层,主要是对dubbo进行各种配置的;
    • 第三层:proxy层,服务接口透明代理,生成服务的客户端 Stub 和服务器端 Skeleton;
    • 第四层:registry层,服务注册层,负责服务的注册与发现;
    • 第五层:cluster层,集群层,封装多个服务提供者的路由以及负载均衡,将多个实例组合成一个服务;
    • 第六层:monitor层,监控层,对rpc接口的调用次数和调用时间进行监控;
    • 第七层:protocol层,远程调用层,封装rpc调用;
    • 第八层:exchange层,信息交换层,封装请求响应模式,同步转异步;
    • 第九层:transport层,网络传输层,抽象mina和netty为统一接口;
    • 第十层:serialize层,数据序列化层。网络传输需要;
  6. Dubbo中的负载均衡算法及其特点

    1)RandomLoadBalance:随机负载均衡,是Dubbo的默认负载均衡策略。

    按照权重分配随机概率,在Dubbo中可以对 Provider设置权重。比如机器性能好的,可以设置大一点的权重,性能差的,可以设置小一点的权重。如果没有在Dubbo Admin中对服务 Provider 设置权重,那么所有的 Invoker 的权重就是一样的,默认是100。

    2)RoundRobinLoadBalance:轮询负载均衡,依次的调用所有的Provider。

    和随机负载均衡策略一样,轮询负载均衡策略也有权重的概念。轮询负载均衡算法可以让RPC调用严格按照我们设置的比例来分配。但是轮询负载均衡算法也有不足的地方,存在慢的Provider累积请求的问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上,导致整个系统变慢。

    3)LeastActiveLoadBalance:最少活跃调用数,相同活跃数的随机。活跃数指调用前后计数差。使慢的 Provider 收到更少请求,因为越慢的 Provider 的调用前后计数差会越大。

    比如:每个服务维护一个活跃数计数器。当A机器开始处理请求,该计数器加1,此时A还未处理完成。若处理完毕则计数器减1。而B机器接受到请求后很快处理完毕。那么A,B的活跃数分别是1,0。当又产生了一个新的请求,则选择B机器去执行(B活跃数最小),这样使慢的机器A收到少的请求。
    4)ConsistentHashLoadBalance:一致性Hash算法。相同参数的请求总是落在同一Provider。当某一台 Provider 崩溃时,原本发往该 Provider 的请求,基于虚拟节点,平摊到其它 Provider,不会引起剧烈变动。

    一致性Hash算法可以和缓存机制配合起来使用。比如有一个服务getUserInfo(String userId)。设置了Hash算法后,相同的userId的调用,都会发送到同一个 Provider。这个 Provider 上可以把用户数据在内存中进行缓存,减少访问数据库或分布式缓存的次数。如果业务上允许这部分数据有一段时间的不一致,可以考虑这种做法。减少对数据库,缓存等中间件的依赖和访问次数,同时减少了网络IO操作,提高系统性能。

    和Dubbo其他的配置类似,多个配置是有覆盖关系的:

    方法级优先,接口级次之,全局配置再次之;

    如果级别一样,则消费方优先,提供方次之;

  7. dubbo中的URL

    protocol://username:password@host:port/path?key=value&key=value

    dubbo://192.168.1.6:20880/moe.cnkirito.sample.HelloService?timeout=3000
    描述一个 dubbo 协议的服务

    zookeeper://127.0.0.1:2181/org.apache.dubbo.registry.RegistryService?application=demo-consumer&dubbo=2.0.2&interface=org.apache.dubbo.registry.RegistryService&pid=1214&qos.port=33333&timestamp=1545721981946
    描述一个 zookeeper 注册中心

    consumer://30.5.120.217/org.apache.dubbo.demo.DemoService?application=demo-consumer&category=consumers&check=false&dubbo=2.0.2&interface=org.apache.dubbo.demo.DemoService&methods=sayHello&pid=1209&qos.port=33333&side=consumer&timestamp=1545721827784
    描述一个消费者
    • protocol:一般是 dubbo 中的各种协议 如:dubbo、thrift、http、zk
    • username/password:用户名/密码
    • host/port:主机IP地址/端口号
    • path:接口名称
    • parameter:参数键值对
  8. dubbo 服务暴露

    Spring IOC容器刷新完毕

    ServiceBean#OnApplicationEvent

    ServiceConfig#export

    (如果需要延迟就延迟,不需要就直接用)

    ServiceConfig#doExport

    (获取注册中心URL,循环调用)

    ServiceConfig#doExportUrls

    ServiceConfig#doExportUrlsFor1Protocol

1、dubbo中”读接口”和”写接口”有什么区别?

3、最小活跃数算法中是如何统计这个活跃数的?

5、服务发布过程中做了哪些事?

6、dubbo都有哪些协议,他们之间有什么特点,缺省值是什么?

7、什么是本地暴露和远程暴露,他们的区别?

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

9、讲讲dubbo服务暴露中本地暴露,并画图辅助说明?

10、一般选择什么注册中心,还有别的选择吗?

11、dubbo中zookeeper做注册中心,如果注册中心集群都挂掉,那发布者和订阅者还能通信吗?(面试高频题)

12、项目中有使用过多线程吗?有的话讲讲你在哪里用到了多线程?(面试高频题)

13、zookeeper的java客户端你使用过哪些?

14、服务提供者能实现失效踢出是什么原理?(高频题)

15、zookeeper的有哪些节点,他们有什么区别?讲一下应用场景。

17、在dubbo中,什么时候更新本地的zookeeper信息缓存文件?订阅zookeeper信息的整体过程是怎么样的?

18、谈一下你们项目架构设计(很多人在回答这个的时候都容易回答SSH或者SSM,注意,所谓是SSH这些是技术选型,不是架构的设计)

19、既然你们项目用到了dubbo,那你讲讲你们是怎么通过dubbo实现服务降级的,降级的方式有哪些,又有什么区别?

20、dubbo监控平台能够动态改变接口的一些设置,其原理是怎样的?

21、既然你说你看过dubbo源码,那讲一下有没有遇到过什么坑?(区分度高,也是检验是否看过源码的试金石)

23、有没有考虑过自己实现一个类似dubbo的RPC框架,如果有,请问你会如果着手实现?(面试高频题,区分度高)

24、你说你用过mybatis,那你知道Mapper接口的原理吗?(如果回答得不错,并且提到动态代理这个关键词会继续往下问,那这个动态代理又是如何通过依赖注入到Mapper接口的呢?)

26、既然你提到了dubbo的服务引用中封装通信细节是用到了动态代理,那请问创建动态代理常用的方式有哪些,他们又有什么区别?dubbo中用的是哪一种?(高频题)

27、除了JDK动态代理和CGLIB动态代理外,还知不知道其他实现代理的方式?(区分度高)

28、你是否了解spi,讲一讲什么是spi,为什么要使用spi?

29、对类加载机制了解吗,说一下什么是双亲委托模式,他有什么弊端,这个弊端有没有什么我们熟悉的案例,解决这个弊端的原理又是怎么样的?

30、既然你对spi有一定了解,那么dubbo的spi和jdk的spi有区别吗?有的话,究竟有什么区别?

31、你提到了dubbo中spi也增加了IoC,那你先讲讲Spring的IoC,然后再讲讲dubbo里面又是怎么做的?

32、你提到了dubbo中spi也增加了AOP,那你讲讲这用到了什么设计模式,dubbo又是如何做的?

Author: Jiayi Yang
Link: https://jiayiy.github.io/2020/06/21/Dubbo/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.