Dubbo面试题
1.Dubbo是什么?
Dubbo是一个分布式/高性能/透明化的RPC服务框架,提供服务自动注册/自动发现等高效的服务治理方案,可以和Spring框架的无缝集成.
分为三层:
Bussiness层:由我们自己提供的接口和实现,还有一些配置信息。
RPC层:封装和实现整个RPC的调用过程,负载均衡,集群容错等核心功能;
remoting层:网络传输协议和数据转换的封装。
主要应用在:
透明化的远程方法调用;
负载均衡和集群容错 ;
服务的自动注册和发现。
Dubbo的核心组件是:
Provider:暴露服务的服务提供方;
Condumer:远程调用服务的服务消费方;
Registry:服务注册和发现的注册中心; Monitor:统计服务的调用次数 和调用时间的监控中心;
Container:服务运行容器
2.Dubbo的服务和注册流程?
1.Provider启动时链接注册中心,并把本机IP/端口/应用信息和提供服务信息发送到注册中心存储;
2.Consumer启动时链接注册中心并会去注册中心去订阅自己需要的提供者信息;
3.注册中心返回服务提供者地址列表给消费者,并缓存到本地。如果有变更,注册中心基于长链接推送变更数据给消费者;
4.服务消费者从提供者的列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,在选另一台进行调用;
5.服务提供者和服务消费者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心.
3.服务暴露的过程?
服务暴露的过程起始于Spring IOC容器刷新完毕之后,会根据配置参数组装成URL, 然后根据URL的参数来进行本地或者远程调用;会通过proxyFactory.getInvoker封装真的实现类invoker,调用服务的对象都封装成 invoker。然后在通过URL参数选择对应的协议来进行protocol.export,默认是 Dubbo 协议。
在第一次暴露的时候会调用 createServer 来创建 Server,默认是 NettyServer。
然后将 export 得到的 exporter 存入一个 Map 中,供之后的远程调用查找,然后会向注册中心注册提供者的信息。
4.服务引入的流程?
服务引入的时机有两种,第一种就是饿汉,另一种是懒汉.
只要 Spring 容器启动都会去回调所有 afterPropertiesSet 方法进行回调,属于一种饿汉式方式(一上来就开干).懒汉式只有当这个服务被注入到其他类中时启动引入流程,默认是懒汉式.
会根据配置参数组装成URL,一般我们会配置注册中心,向注册中心注册消费者信息,并且订阅提供者/配置/路由等节点.
5.Spi机制是什么?
SPI 是 Service Provider Interface,基于接口的编程+策略模式+配置文件”组合实现的动态加载机制。主要用于框架中,框架定义好接口,不同的使用者有不同的需求,因此需要有不同的实现,而 SPI 就通过定义一个特定的位置,Java SPI 约定在 Classpath 下的 META-INF/services/ 目录里创建一个以服务接口命名的文件,然后文件里面记录的是此 jar 包提供的具体实现类的全限定名。
数据库驱动加载接口/Dubbo
dubbo spi和Java spi区别?
java spi:会一次性的加载所有的扩展实现,若有的扩展很耗时,但也没用上,很浪费资源.
dubbo spi:
对dubbo进行扩展,不需要改动dubbo源码;
延迟加载,可以一次只加载自己需要的扩展实现;
增加对拓展点ioc和aop的支持.
6.Dubbo有哪些注册中心?
1.Zookeeper:基于分布式协调系统zookeeper实现,采用zookeeper的watch机制实现数据变更.
2.Muticast:不需要任何中心节点,只要广播地址就能进行服务注册和发现,基于网络中组播传输的实现.
3.nacos:SpringCloudAlibaba+nacos+dubbo
4.redis:基于redis发布订阅模式通知数据变更.
7.Dubbo注册中心挂了,发布者和订阅者还能进行通讯吗?
可以,启动Dubbo时,消费者会从Zookeeper拉取注册的生产者的地址接口数据缓存到本地,每次调用时,按照本地存储的地址进行调用.
8.Dubbo和SpringCloud有什么关系?
Dubbo是SOA时代的产物,关注点是主要用于服务的调用,流量分发,流量监控和熔断.
SpringCloud诞生在微服务时代,考虑的是微服务治理的方方面面,依托于Spring/Spring boot优势之上.
Dubbo使用的是Netty这样的NIO接口,基于TCP协议进行传输的.配合Hession序列化完成RPC通信.
SpringCloud是基于Http协议的Rest接口调用远程通信,相对来说,Http请求会有更大的报文,占的带宽也更大. Rest相比较RPC更为灵活,只依赖相互的约定,不存在代码级别的强依赖.
9.怎样实现动态感知服务下线?
Dubbo Zookeeper注册中心采用的是事件通知和客户端拉取方式.消费者第一次订阅拉取对应目录上的全量数据,然后在订阅节点注册一个watcher, 一旦目录节点下的任何数据变化,zookeeper将会通过watcher通知客户端,客户端收到通知,将会拉取该目录下的全量数据,并重新注册watcher.
zookeeper提供了心跳机制,定时向各个服务提供者发送一个请求,如果长时间没有响应,服务中心就认为该服务提供者已经挂了,并将剔除.
10.Dubbo的负载均衡策略?
使用的模板设计模式,不同的负载均衡算法的方法实现AbstractLoadBalance ,AbstractLoadBalance 实现LoadBalance接口,重写select中的doSelect方法.
RoundRobin LocadBalance:轮询选取提供者的策略,平均分布, 但是存在请求累计的问题.
RandomLoadBalnce:随机选取提供者的策略(默认)
LeastActiveLoadBalance:最少活跃调用策略,解决慢提供者接收更少的请求.而且活跃数都是从 0 加起来的,来一个请求活跃数+1,一个请求处理完成活跃数-1,所以活跃数少也能变相的体现处理的快.
ConsistentHashLoadBalance:一致性hash算法.将服务器的 IP 等信息生成一个 hash 值,将这个值投射到圆环上作为一个节点,然后当 key 来查找的时候顺时针查找第一个大于等于这个 key 的 hash 值的节点.使相同参数的请求总是发到同一个提供者,一台机器宕机,可以基于虚拟节点,分摊至其他提供者,避免引起 提供者的剧烈运动.
11.Dubbo的集群容错方案有哪些?
1.FailoverClusterInvoker
这个 cluster 实现的是失败自动切换功能,简单的说一个远程调用失败,它就立马换另一个,当然是有重试次数的。
2.FailfastClusterInvoker
这个 cluster 只会进行一次远程调用,如果失败后立即抛出异常,也就是快速失败,它适合于不支持幂等的一些调用。
3.FailsafeClusterInvoker
这个 cluster 是一种失败安全的 cluster,也就是调用出错仅仅就日志记录一下,然后返回了一个空结果,适用于写入审计日志等操作。
4.FailbackClusterInvoker
这个 cluster 会在调用失败后,记录下来这次调用,然后返回一个空结果给服务消费者,并且会通过定时任务对失败的调用进行重调。适合执行消息通知等最大努力场景.
5.ForkingClusterInvoker
这个 cluster 会在运行时把所有 invoker 都通过线程池进行并发调用,只要有一个服务提供者成功返回了结果,doInvoke 方法就会立即结束运行。适合用在对实时性要求比较高读操作。
6.BroadcastClusterInvoker
这个 cluster 会在运行时把所有 invoker 逐个调用,然后在最后判断如果有一个调用抛错的话,就抛出异常。 适合通知所有提供者更新缓存或日志等本地资源信息的场景。
12.Dubbo有哪些协议?
1.dubbo:
单一长链接和nio异步通讯,适合大并发小数据量的服务调用,以及消费者数量远大于提供者.
2.rmi:
采用jdk标准的rmi协议实现,传输参数和返回参数对象需要实现Serializable,使用java标准序列化标准.使用阻塞短链接.
3.hession:
集成hession服务,基于Http通讯,采用Servlet暴露服务,Dubbo内嵌jetty作为服务器时默认实现.
4.redis:
基于redis实现rpc协议;
5.memchance:
基于memchance实现rpc协议;
6.Http:
基于Http表单提交的远程调用协议.
13.Dubbo使用的设计模式?
1.动态代理模式:Dubbo扩展Java spi类ExtensionLoader的Adaptive实现是典型的动态代理模式.
2.观察者模式:Dubbo的provider启动时,需要与注册中心交互 ,先注册自己的服务,在订阅自己的服务,订阅时采用的时观察者模式,开启一个Listener. 注册中心会每5s定时检测是否有服务更新,如果有更新,则向服务提供者发送一个notify消息,provider接受到消息后,运行NotifyListerner的notify方法,执行监听器的方法.
3.工厂模式