2023春招必备:Dubbo面试题(上)
1、为什么需要 Dubbo?
因为是阿里开源项目,国内很多互联网公司都在用,已经经过很多线上考验。内部使用了 Netty、 Zookeeper,保证了高性能高可用性。
使用 Dubbo 可以将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,可用于提高业务复用灵活扩展,使前端应用能更快速的响应多变的市场需求。
下面这张图可以很清楚的诠释,最重要的一点是,分布式架构可以承受更大规模的并发流量。
下面是 Dubbo 的服务治理图。
2、Dubbo 的主要应用场景?
通常有四点,如下:
RPC 分布式服务,拆分应用进行服务化,提高开发效率,调优性能,节省竞争资源配置管理,解决服务的地址信息剧增,配置困难的问题 服务依赖,解决服务间依赖关系错踪复杂的问题 服务扩容,解决随着访问量的不断增大,动态扩展服务提供方的机器的问题
3、Dubbo 的核心功能?
Dubbo主要就是如下 3 个核心功能:
(1)Remoting:网络通信框架,提供对多种 NIO 框架抽象封装,包括“同步转异步”和“请求-响应”模式的信息交换方式。
(2)Cluster:服务框架,提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持。
(3)Registry:服务注册,基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器。
4、Dubbo 服务注册与发现的流程?
1、流程说明:
Provider(提供者)绑定指定端口并启动服务 指供者连接注册中心,并发本机IP、端口、应用信息和提供服务信息发送至注册中心存储 Consumer(消费者),连接注册中心 ,并发送应用信息、所求服务信息至注册中心 注册中心根据 消费 者所求服务信息匹配对应的提供者列表发送至Consumer 应用缓存。 Consumer 在发起远程调用时基于缓存的消费者列表择其一发起调用。 Provider 状态变更会实时通知注册中心、在由注册中心实时推送至Consumer
2、设计的原因:
Consumer 与Provider 解偶,双方都可以横向增减节点数。 注册中心对本身可做对等集群,可动态增减节点,并且任意一台宕掉后,将自动切换到另一台去中心化,双方不直接依懒注册中心,即使注册中心全部宕机短时间内也不会影响服务的调用服务提供者无状态,任意一台宕掉后,不影响使用
5、Dubbo 的服务调用流程?
下图为dubbo官方的一张调用图
从client到server经历了编码,序列化,反序列化,解码 的正常网络调用流程, 在nettyServer中处理
client采用代理的机制
server处理请求的方式通常为分发请求到线程池,同步阻塞或异步非阻塞返回结果
6、Dubbo 支持哪些协议,每种协议的应用场景、优缺点?
协议名程 | 传输 | 序列化 | 连接 | 使用场景 |
---|---|---|---|---|
dubbo默认 | mina、netty、 grizzy | dubbo、hessian2(默认) 、java、 json | dubbo缺省采用单一长连接和NIO异步通讯 | 1.传入传出参数数据包较小 2. 消费者 比提供者多 3. 常规远程服务方法调用 4.不适合传送大数据量的服务,比如文件、传视务 |
rni | Java RMI | Java 标准序列化 | 连接个数: 多连接 连接方式: 短连接 传输协议: TCP/IP 传输方式: BIO | 1.常规RFC调用 2.与原RMI客户端互操作 3.可传文件 4.不支持防火墙穿透 |
hessian | Servlet容器 | hessian二进制序列化 | 连接个数:多连接 连接方式: 短连接 传输协议: HTTP | 1. 提供者比消费者多 2.可传文件 3.跨语言传输 |
http | Servlet容器 | 表单序列化 | 连接个数:多连接 连接方式: 短连接 传输协议: HTTP 传输方式:同步传输 | 1.提供者多余消费者 2.数据包混合 |
webservice | HTTP | SOAP文件序列化 | 连接个数: 多连接 连接方式: 短连接 传输协议: HTTP | 1.系统集成 2.跨语言调用 |
thrift | rift RPC实现集成,并在基础上修改了报文头 | 长连接、NIO异步传输 |
还有三种,混个眼熟就行:Memcached 协议、Redis 协议、Rest 协议。
上图基本上把序列化的方式也罗列出来了。
详细请参考:Dubbo 官网:http://dubbo.apache.org/zh-cn/docs/user/references/protocol/dubbo.html
7、Dubbo 有些哪些注册中心?
推荐使用 Zookeeper 作为注册中心,还有 Redis、Multicast、Simple 注册中心,但不推荐。
8、Dubbo 如何实现服务治理?
Dubbo服务治理,我们可以分成3个点:
1.调用链路自动生成 一个大型的分布式系统,或者说是用现在流行的微服务架构来说吧,分布式系统由大量的服务组 成。
那么这些服务之间互相是如何调用的?调用链路是啥?
说实话,几乎到后面没人搞的清楚了,因为服务实在太多了,可能几百个甚至几千个服务。
那就需要基于 dubbo 做的分布式系统中,对各个服务之间的调用自动记录下来,然后自动将各个服务之间的依赖关系和调用链路生成出来,做成一张图,显示出来,大家才可以看到对吧。
2.服务访问压力以及时长统计
需要自动统计各个接口和服务之间的调用次数以及访问延时,而且要分成两个级别。
一个级别是接口粒度,就是每个服务的每个接口每天被调用多少次,TP50/TP90/TP99,三个档次的请求延时分别是多少;
TP50:表示满足百分之五十的网络请求所需的最低耗时。 TP90:表示满足百分之九十的网络请求所需的最低耗时。 TP99:表示满足百分之九十九的网络请求所需的最低耗时。
举个例子:有四次请求耗时分别为:
10ms,1000ms,100ms,2ms
那么我们可以这样计算TP99:4次请求中,99%的请求数为4*0.99,进位取整也就是4次,满足这全部4次请求的的最低耗时为1000ms,也就是TP99的答案是1000ms。
第二个级别是从源头入口开始,一个完整的请求链路经过几十个服务之后,完成一次请求,每天全链路走多少次,全链路请求延时的 TP50/TP90/TP99,分别是多少。
这些东西都搞定了之后,后面才可以来看当前系统的压力主要在哪里,如何来扩容和优化啊。
3.其它
服务分层(避免循环依赖)调用链路失败监控和报警 服务鉴权
每个服务的可用性的监控(接口调用成功率?几个 9?99.99%,99.9%,99%)
9、Dubbo 的注册中心集群挂掉,如何正常消费?
可以的,消费者在启动时,消费者会从zk拉取注册的生产者的地址接口等数据,缓存在本地。
每次调用时,按照本地存储的地址进行调用。
消费者本地有一个生产者的列表,他会按照列表继续工作,倒是无法从注册中心去同步最新的服务列表,短期的注册中心挂掉是不要紧的,但一定要尽快修复。
挂掉是不要紧的,但前提是你没有增加新的服务(节点没有变动),如果你要调用新的服务,则是不能办到的。
10、Dubbo 集群提供了哪些负载均衡策略?
负载均衡策略 | 说明 |
---|---|
Random LoadBalance | 随机,按权重设置随机概率(默认) |
RoundRobin LoadBalance | 轮询,按公约后的权重设置轮询比率 |
LeastActive LoadBalance | 最少活跃调用数,相同活跃数的随机 |
ConsistentHash LoadBalance | 一致性 Hash,相同参数的请求总是发到同一提供者 |
Dubbo 的集群容错方案有哪些?
集群容错方案 | 说明 |
---|---|
Failover Cluster | 失败自动切换,自动重试其它服务器(默认) |
Failfast Cluster | 快速失败,立即报错,只发起一次调用 |
Failsafe Cluster | 失败安全,出现异常时,直接忽略 |
Failback Cluster | 失败自动恢复,记录失败请求,定时重发 |
Forking Cluster | 并行调用多个服务器,只要一个成功即返回 |
Broadcast Cluster | 广播逐个调用所有提供者,任意一个报错则报错 |
11、Dubbo 支持哪些序列化方式?
在 Dubbo RPC 中,同时支持多种序列化方式:
1.Dubbo 序列化:阿里尚未开发成熟的高效 Java 序列化实现,阿里不建议在生产环境使用它
2.Hessian2 序列化:Hessian 是一种跨语言的高效二进制序列化方式。但这里实际不是原生的Hessian2 序列化,而是阿里修改过的Hessian Lite,它是 Dubbo RPC 默认启用的序列化方式
3.Json 序列化:目前有两种实现,一种是采用的阿里的 Fastjson 库,另一种是采用 Dubbo中自己实现的简单 Json库,但其实现都不是特别成熟,而且 Json 这种文本序列化性能一般不如上面两种二进制序列化。
4.Java 序列化:主要是采用 JDK 自带的 Java 序列化实现,性能很不理想。
12、说说一次 Dubbo 服务请求流程?
基本工作流程:
节点 | 角色明 |
---|---|
Provider | 暴露服务的服务提供方 |
Consumer | 调用远程服务的服务消费方 |
Registry | 服务注册与发现的注册中心 |
Monitor | 统计服务的调用次数和调用时间的监控中心 |
Container | 服务运行容器 |
13、能说下Dubbo的总体的调用过程吗?
调用过程图:
1.Proxy持有一个Invoker对象,使用Invoker调用
2.之后通过Cluster进行负载容错,失败重试
3.调用Directory获取远程服务的Invoker列表
4.负载均衡用户配置了路由规则,则根据路由规则过滤获取到的Invoker列表用户没有配置路由规则或配置路由后还有很多节点,则使用LoadBalance方法做负载均衡,选用一个可以调用的Invoker
5.经过一个一个过滤器链,通常是处理上下文、限流、计数等。
6.会使用Client做数据传输
7.私有化协议的构造(Codec)
8.进行序列化
9.服务端收到这个Request请求,将其分配到ThreadPool中进行处理
10.Server来处理这些Request
11.根据请求查找对应的Exporter
12.之后经过一个服务提供者端的过滤器链
13.然后找到接口实现并真正的调用,将请求结果返回
14、说说Dubbo的分层?
分层图:
从大的范围来说,dubbo分为三层
business业务逻辑层由我们自己来提供,接口和实现还有一些配置信息
RPC层就是真正的RPC调用的核心层,封装整个RPC的调用过程、负载均衡、集群容错、代理
remoting则是对网络传输协议和数据转换的封装。
从API、SPI角度来说,dubbo分为2层
Service和Config两层可以认为是API层,主要提供给API使用者,使用者只需要配置和完成业务代码就可以了。
后面所有的层级是SPI层,主要提供给扩展者使用主要是用来做Dubbo的二次开发扩展功能。
再划分到更细的层面,就是图中的10层模式。
15、说说 Dubbo 工作原理
工作原理分 10 层:
第一层:service 层,接口层,给服务提供者和消费者来实现的(留给开发人员来实现);
第二层:config 层,配置层,主要是对 Dubbo 进行各种配置的,Dubbo 相关配置;
第三层:proxy 层,服务代理层,透明生成客户端的 stub 和服务单的 skeleton,调用的是接口,实现类没有,所以得生成代理,代理之间再进行网络通讯、负责均衡等;
第四层:registry 层,服务注册层,负责服务的注册与发现;
第五层:cluster 层,集群层,封装多个服务提供者的路由以及负载均衡,将多个实例组合成一个服务;
第六层:monitor 层,监控层,对 rpc 接口的调用次数和调用时间进行监控;第七层:protocol 层,远程调用层,封装 rpc 调用;
第八层:exchange 层,信息交换层,封装请求响应模式,同步转异步;
第九层:transport 层,网络传输层,抽象 mina 和 netty 为统一接口;
第十层:serialize 层,数据序列化层。
这是个很坑爹的面试题,但是很多面试官又喜欢问,你真的要背么?你能背那还是不错的,我建议不要背,你就想想 Dubbo 服务调用过程中应该会涉及到哪些技术,把这些技术串起来就 OK 了。
16、注册中心挂了,consumer 还能不能调用 provider?
可以。
因为刚开始初始化的时候,consumer 会将需要的所有提供者的地址等信息拉取到本地缓存,所以注册中心挂了可以继续通信。
但是 provider 挂了,那就没法调用了。
PS:consumer 本地缓存服务列表。
17、怎么实现动态感知服务下线的呢?
服务订阅通常有 pull 和 push 两种方式:
pull 模式需要客户端定时向注册中心拉取配置; push 模式采用注册中心主动推送数据给客户端。
Dubbo ZooKeeper 注册中心采用是事件通知与客户端拉取方式。
服务第一次订阅的时候将会拉取对应目录下全量数据,然后在订阅的节点注册一个 watcher。
一旦目录节点下发生任何数据变化, ZooKeeper 将会通过 watcher 通知客户端。
客户端接到通知,将会重新拉取该目录下全量数据,并重新注册 watcher。
利用这个模式,Dubbo 服务就可以做到服务的动态发现。
注意:ZooKeeper 提供了“心跳检测”功能,它会定时向各个服务提供者发送一个请求(实际上建立的是一个 socket 长连接),如果长期没有响应,服务中心就认为该服务提供者已经“挂了”,并将其剔除。
18、服务提供者没挂,但在注册中心里看不到?
首先,确认服务提供者是否连接了正确的注册中心,不只是检查配置中的注册中心地址,而且要检查实际的网络连接。
其次,看服务提供者是否非常繁忙,比如压力测试,以至于没有CPU片段向注册中心发送心跳,这种情况减小压力将自动恢复。
19、说说Dubbo的优先级配置
配置优先级别
1.以timeout为例,显示了配置的查找顺序,其他retries,loadbalance等类似。
(1) 方法级优先,接口级次之,全局配置在次之
(2) 如果级别一样,则消费方优先,提供方次之
(3) 其中,服务提供方配置,通过URL经由注册中心传递给消费方
2.建议由服务提供方设置超时,因为一个方法需要执行多长时间,服务提供方更清楚,如果一个消费方同时引用多个服务,就不需要关心每个服务的超时设置。
20、负载平衡的意义什么?
在计算中,负载平衡可以改善跨计算机,计算机集群,网络链接,中央处理单元或磁盘驱动器等多种计算资源的工作负载分布。负载平衡旨在优化资源使用,最大化吞吐量,最小化响应时间并避免任何单一资源 的过载。使用多个组件进行负载平衡而不是单个组件可能会通过冗余来提高可靠性和可用性。负载平衡通常涉及专用软件或硬件,例如多层交换机或域名系统服务器进程。
22、常见负载均衡算法有哪些?
轮询 加权轮询 随机 最少连接 源地址hash
22、你知道哪些限流算法?
限流算法有四种常见算法:
计数器算法(固定窗口)滑 动窗口 漏桶算法 令牌桶算法
硬核面试题推荐
重点面试题:每天100w次登陆请求, 8G 内存该如何设置JVM参数?来看看年薪100W的架构师,是怎么配置的 核心面试题:为什么新生代要两个Survivor区? 一个不行吗? 核心面试题目:什么是 回表查询、索引覆盖、最左匹配原则?说说聚集索引、非聚集索引的区别?
面试重点难题:Mysql如何实现RR级隔离时,不会幻读? 核心面试难题:Java的 对象 不一定在堆上分配,为什么? 核心面试题:MVCC、间隙锁、Undo Log链、表级锁、行级锁、页级锁、共享锁、排它锁、记录锁等等
硬核文章推荐
一文搞懂:Java高手必备之 Mpsc 无锁队列 (史上最全) 一文搞懂:微服务核心组件 Nacos(史上最全) 一文搞懂:微服务核心组件 sentinel(史上最全) 一文秒懂:多级时间轮,最顶尖的Java调度算法 一文搞懂:缓存之王 Caffeine 架构、源码、原理(5W长文) 高性能组件:环形队列、 条带环形队列 Striped-RingBuffer 架构分析 一文穿透:队列之王 Disruptor 原理、架构、源码 如何优雅的使用 单例模式 ?来看看缓存之王 Caffeine 、链路之王 Skywalking 是如何做的吧! 细思极恐:Java官方JVM 为啥要叫做 HotSpot JVM?背后的水,不知道有多深!!! Java核心实操:内存溢出 实战、内存泄漏实战
硬核电子书
本文收录于:《尼恩Java 面试宝典》V21版
长按二维码,点击“识别图中二维码”即可查看老架构师尼恩个人微信,发暗号 “领电子书” 给尼恩,获取最新PDF。
最新的《尼恩Java面试宝典》
极致经典,不断升级,目前最新为V21
尼恩Java高并发三部曲
《Java高并发核心编程-卷1(加强版)》,不断升级
《Java高并发核心编程-卷2(加强版)》,不断升级
《Java高并发核心编程-卷3(加强版)》,不断升级
尼恩架构笔记100篇+,不断添加