做者 | 科技缪缪
php
来源 | 科技缪缪(ID:kejimiumiu)java
头图 | CSDN 下载自东方IC
Dubbo 自己并不复杂,并且官方文档写的很是清楚详细,面试中 Dubbo 的问题通常不会不少,从分层到工做原理、负载均衡策略、容错机制、SPI 机制基本就差很少了,最大的一道大题通常就是怎么设计一个 RPC 框架了,可是若是你工做原理分层都搞明白了这个问题其实也就至关于回答了不是吗。
程序员
说说 Dubbo 的分层?
从大的范围来讲,dubbo 分为三层,business 业务逻辑层由咱们本身来提供接口和实现还有一些配置信息,RPC 层就是真正的 RPC 调用的核心层,封装整个 RPC 的调用过程、负载均衡、集群容错、代理,remoting 则是对网络传输协议和数据转换的封装。面试
划分到更细的层面,就是图中的10层模式,整个分层依赖由上至下,除开 business 业务逻辑以外,其余的几层都是 SPI 机制。算法
能说下 Dubbo 的工做原理吗?
服务启动的时候,provider 和 consumer 根据配置信息,链接到注册中心register,分别向注册中心注册和订阅服务浏览器
register根据服务订阅关系,返回 provider 信息到 consumer,同时 consumer 会把 provider 信息缓存到本地。若是信息有变动,consumer会收到来自register的推送缓存
consumer生成代理对象,同时根据负载均衡策略,选择一台provider,同时定时向monitor记录接口的调用次数和时间信息安全
拿到代理对象以后,consumer经过代理对象发起接口调用服务器
provider收到请求后对数据进行反序列化,而后经过代理调用具体的接口实现
网络
为何要经过代理象通讯?
主要是为了实现接口的透明代理,封装调用细节,让用户能够像调用本地方法同样调用远程方法,同时还能够经过代理实现一些其余的策略,好比:
一、调用的负载均衡策略
二、调用失败、超时、降级和容错机制
三、作一些过滤操做,好比加入缓存、mock数据
四、接口调用数据统计
说说服务暴露的流程?
在容器启动的时候,经过ServiceConfig解析标签,建立dubbo标签解析器来解析dubbo的标签,容器建立完成以后,触发ContextRefreshEvent事件回调开始暴露服务
经过ProxyFactory获取到invoker,invoker包含了须要执行的方法的对象信息和具体的URL地址
再经过DubboProtocol的实现把包装后的invoker转换成exporter,而后启动服务器server,监听端口
最后RegistryProtocol保存URL地址和invoker的映射关系,同时注册到服务中心
说说服务引用的流程?
服务暴露以后,客户端就要引用服务,而后才是调用的过程。
首先客户端根据配置文件信息从注册中心订阅服务
以后DubboProtocol根据订阅的获得provider地址和接口信息链接到服务端server,开启客户端client,而后建立invoker
invoker建立完成以后,经过invoker为服务接口生成代理对象,这个代理对象用于远程调用provider,服务的引用就完成了
有哪些负载均衡策略?
加权随机:假设咱们有一组服务器 servers = [A, B, C],他们对应的权重为 weights = [5, 3, 2],权重总和为10。如今把这些权重值平铺在一维坐标值上,[0, 5) 区间属于服务器 A,[5, 8) 区间属于服务器 B,[8, 10) 区间属于服务器 C。接下来经过随机数生成器生成一个范围在 [0, 10) 之间的随机数,而后计算这个随机数会落到哪一个区间上就能够了。
最小活跃数:每一个服务提供者对应一个活跃数 active,初始状况下,全部服务提供者活跃数均为0。每收到一个请求,活跃数加1,完成请求后则将活跃数减1。在服务运行一段时间后,性能好的服务提供者处理请求的速度更快,所以活跃数降低的也越快,此时这样的服务提供者可以优先获取到新的服务请求。
一致性hash:经过hash算法,把provider的invoke和随机节点生成hash,并将这个 hash 投射到 [0, 2^32 - 1] 的圆环上,查询的时候根据key进行md5而后进行hash,获得第一个节点的值大于等于当前hash的invoker。
加权轮询:好比服务器 A、B、C 权重比为 5:2:1,那么在8次请求中,服务器 A 将收到其中的5次请求,服务器 B 会收到其中的2次请求,服务器 C 则收到其中的1次请求。
集群容错方式有哪些?
Failover Cluster失败自动切换:dubbo的默认容错方案,当调用失败时自动切换到其余可用的节点,具体的重试次数和间隔时间可用经过引用服务的时候配置,默认重试次数为1也就是只调用一次。
Failback Cluster快速失败:在调用失败,记录日志和调用信息,而后返回空结果给consumer,而且经过定时任务每隔5秒对失败的调用进行重试
Failfast Cluster失败自动恢复:只会调用一次,失败后马上抛出异常
Failsafe Cluster失败安全:调用出现异常,记录日志不抛出,返回空结果
Forking Cluster并行调用多个服务提供者:经过线程池建立多个线程,并发调用多个provider,结果保存到阻塞队列,只要有一个provider成功返回告终果,就会马上返回结果
Broadcast Cluster广播模式:逐个调用每一个provider,若是其中一台报错,在循环调用结束后,抛出异常。
了解Dubbo SPI机制吗?
SPI 全称为 Service Provider Interface,是一种服务发现机制,本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类,这样能够在运行时,动态为接口替换实现类。
Dubbo也正是经过SPI机制实现了众多的扩展功能,并且dubbo没有使用java原生的SPI机制,而是对齐进行了加强和改进。
SPI在dubbo应用不少,包括协议扩展、集群扩展、路由扩展、序列化扩展等等。
使用方式能够在META-INF/dubbo目录下配置:
key=com.xxx.value
而后经过dubbo的ExtensionLoader按照指定的key加载对应的实现类,这样作的好处就是能够按需加载,性能上获得优化。
若是让你实现一个RPC框架怎么设计?
首先须要一个服务注册中心,这样consumer和provider才能去注册和订阅服务
须要负载均衡的机制来决定consumer如何调用客户端,这其中还固然要包含容错和重试的机制
须要通讯协议和工具框架,好比经过http或者rmi的协议通讯,而后再根据协议选择使用什么框架和工具来进行通讯,固然,数据的传输序列化要考虑
除了基本的要素以外,像一些监控、配置管理页面、日志是额外的优化考虑因素。
那么,本质上,只要熟悉一两个RPC框架,就很容易想明白咱们本身要怎么实现一个RPC框架。
更多精彩推荐 ☞感动!盲人计算机科学家研发语音浏览器,致力科技改善盲人生活 ☞1024 程序员节重要议程曝光,开源技术英雄会聊开源“真心话” ☞蓝色版苹果iPhone 12开箱上手视频流出;谷歌回应司法部反垄断诉讼:存在严重漏洞;Git 2.29 稳定版发布|极客头条 ☞我是一个平平无奇的AI神经元 ☞对话阿里云:开源与自研如何共处? ☞10 月中旬的 Medalla 测试网失常:如何开始,将如何结束?
点分享点点赞点在看