什么是DUBBO?
Dubbo 是一个分布式服务框架,致力于提供高性能和透明化的 RPC 远程服务调用方案,以及 SOA 服务治理方案。
聊一下DUBBO是如何进行服务的注册与发现的?
- 服务提供者启动的时候,会向注册中心提供自己提供的服务。
- 服务消费者在启动的时候,向注册中心订阅自己所需的服务。
- 注册中心会返回服务提供者地址列表给消费者,如果有变更,注册中心会基于长连接推送变更数据给消费者。
- 服务消费者Consumer,从提供者地址列表基于负载均衡算法,选取一台进行调用,如果调用失败,再换一台。
Dubbo主要分了几层?
- 接口服务层:包含了提供者和消费者对应的接口和实现。
- 配置层: 对外配置接口,通过ServiceConfig和ReferenceConfig来实现。
- 服务代理层:服务接口的透明代理,dubbo实际调用都是通过代理来实现的。
- 服务注册层:封装服务地址的注册和发现,以服务URL为中心。
- 路由层: 封装多个提供者的路由和负载均衡。
- 监控层:监控生产者和消费者的调用次数以及时间等监控。
- 远程调用层:封装RPC调用
- 信息交换层:封装请求响应,同步转异步等。
- 网络传输层:使用netty或者mina等网络传输框架 10.序列化层: 数据序列化。
服务的注册流程?
- 通过 ServiceConfig 解析标签,创建 dubbo 标签解析器来解析 dubbo 的标签。容器创建完成之后,触发 ContextRefreshEvent 事件回调开始暴露服务;
- 通过 ProxyFactory.getInvoker 方法,并利用 Javassist 或 JdkProxyFactory 来进行动态代理,将服务暴露接口封装成 Invoker 对象,里面包含了需要执行的方法的对象信息和具体的 URL 地址;
- 再通过 DubboProtocol 的实现把包装后的 Invoker 转换成 Exporter;
- 然后启动服务器 server,监听客户端的请求。
- 最后 RegistryProtocol 保存 URL 地址和 Invoker 映射关系,同时注册到服务中心。
服务的引用流程?
- 首先,客户端根据 config 文件信息从注册中心订阅服务。首次会全量缓存到本地,后续的更新会监听动态更新到本地。
- 接着,DubboProtocol 根据 provider 的地址和接口信息连接到服务端 server。开启客户端 client,然后创建invoker。
- 然后,通过 invoker 为服务接口生成代理对象,这个代理对象用于远程调用 provider,至此完成了服务引用。
服务总体调用流程?
- Proxy 持有一个 Invoker 对象,使用 Invoker 调用;
- 之后通过 Cluster 进行负载容错,失败重试;
- 调用 Directory 获取远程服务的 Invoker 列表;
- 负载均衡
- 用户配置了路由规则,则根据路由规则过滤获取到的 Invoker 列表;
- 用户没有配置路由规则,或配置路由后还有很多节点时,则使用 LoadBalance 方法做负载均衡,选用一个可以调用的 Invoker。
- 经过一个一个过滤器链,通常是处理上下文、限流、计数等;
- 会使用 Client 做数据传输;
- 私有化协议的构造(Codec);
- 进行序列化;
- 服务端收到这个 Request 请求,将其分配到 ThreadPool 中处理;
- Server 来处理这些 Request;
- 根据请求查找对应的 Exporter;
- 之后经过一个服务提供者端的过滤器链;
- 然后找到接口实现并真正的调用,将请求结果返回。
Dubbo多版本如何解决?
可以直接通过 Dubbo 配置中的 version 版本来控制多个版本即可。比如:
<dubbo:service interface="com.xxxx.rent.service.IDemoService" ref="iDemoServiceFirst" version="1.0.0"/>
<dubbo:service interface="com.xxxx.rent.service.IDemoService" ref="iDemoServiceSecond" version="1.0.1"/>
老版本 version=1.0.0,新版本 version=1.0.1。
聊聊Dubbo SPI机制?
- SPI(Service Provider Interface)是一种服务发现机制。其实就是将结构的实现类写入配置当中,在服务加载的时候读取配置文件,加载实现类。这样就可以在运行的时候,动态帮助接口替换实现类。
- Dubbo 的 SPI 其实是对 Java 的 SPI 进行了一种增强,可以按需加载实现类之外,增加了 IOC 和 AOP 的特性,还有自适应扩展机制。
- SPI 在 dubbo 应用很多,包括协议扩展、集群扩展、路由扩展、序列化扩展等。
- Dubbo 对于文件目录的配置分为了三类:
- META-INF/services/ 目录:该目录下的 SPI 配置文件是为了用来兼容 Java SPI;
- META-INF/dubbo/ 目录:该目录存放用户自定义的 SPI 配置文件:key=com.xxx.xxx;
- META-INF/dubbo/internal/ 目录:该目录存放 Dubbo 内部使用的 SPI 配置文件。
DubboSPI和JDKSPI的区别?
- JavaSPI:在查找扩展实现类的时候遍历SPI的配置文件,并将实现类全部实例化。
- DubboSPI:
- 对Dubbo进行扩展不需要改动Dubbo源代码
- 支持延迟加载
- 增加了对扩展点IOC和AOP的支持。
- Dubbo的扩展机制很好的支持第三方IOC容器,默认支持Spring Bean。
Dubbo有哪些负载均衡策略?
- 加权随机 1.比如我们有三台服务器 [A, B, C],给他们设置权重为 [4, 5, 6],然后将这三个数平铺在水平线上,和为 15。然后在 15 以内生成一个随机数,0~4 是服务器 A,4~9 是服务器 B,9~15 是服务器 C。
- 最小活跃数
- 每个服务提供者对应一个活跃数 active。初始情况下,所有服务提供者活跃数均为 0。每收到一个请求,活跃数加 1,完成请求后则将活跃数减 1。
- 在服务运行一段时间后,性能好的服务提供者处理请求的速度更快,因此活跃数下降的也越快,此时这样的服务提供者能够优先获取到新的服务请求。
- 一致性Hash
集群容错方式有哪些?
- Failover Cluster 失败自动切换:dubbo 的默认容错方案,当调用失败时自动切换到其他可用的节点。具体的重试次数和间隔时间可用通过引用服务的时候配置。默认重试次数为 1 即只调用一次;
- Failback Cluster 失败自动恢复:在调用失败,记录日志和调用信息,然后返回空结果给 consumer,并且通过定时任务每隔 5 秒对失败的调用进行重试;
- Failfast Cluster 快速失败:只会调用一次,失败后立刻抛出异常;
- Failsafe Cluster 失败安全:调用出现异常,记录日志不抛出,返回空结果;
- Forking Cluster 并行调用多个服务提供者:通过线程池创建多个线程,并发调用多个 provider,结果保存到阻塞队列。只要有一个 provider 成功返回了结果,就会立刻返回结果;
- Broadcast Cluster 广播模式:逐个调用每个 provider。如果其中一台报错,在循环调用结束后,抛出异常。
服务提供者能实现失效踢出是什么原理?
Zookeeper 中的节点是有生命周期的,具体的生命周期取决于节点的类型。节点主要分为持久(Persistent)节点和临时(Ephemeral)节点 。
ps:文章参考:mp.weixin.qq.com/s/S2ckynSFD…