首先我们得知道什么是Dubbo?如果你连这个都不知道,那面试官根本不会往下问。
Dubbo是阿里巴巴开源的基于 Java 的高性能 RPC 分布式服务框架,现已成为 Apache 基金会孵化项目。
- 第一层的 Business 业务逻辑层由我们自己来提供接口和实现还有一些配置信息。
- 第二层的 RPC 调用的核心层负责封装和实现整个 RPC 的调用过程、负载均衡、 集群容错、代理等核心功能。
- Remoting 则是对网络传输协议和数据转换的封装。
- 根据 Dubbo 官方文档的介绍,Dubbo 提供了六大核心能力:面向接口代理的高性能 RPC 调用、 智能容错和负载均衡、服务自动注册和发现、高度可扩展能力、运行期流量调度、可视化的服务治理与运维。
一、为什么要用Dubbo?
随着服务化的进一步发展,服务越来越多,服务之间的调用和依赖关系也越来越复杂,诞生了面向服务的架构体系(SOA),也因此衍生出了一系列相应的技术,如对服务提供、服务调用、连接处理、通信协议、序列化方式、服务发现、服务路由、日志输出等行为进行封装的服务框架,就这样为分布式系统的服务治理框架就出现了,Dubbo 也就这样产生了。
二、Dubbo内置了哪几种服务容器?
- Spring Container
- Jetty Container
- Log4j Container
Dubbo 的服务容器只是一个简单的 Main 方法,并加载一个简单的 Spring 容器,用于暴露服务。
三、Dubbo是如何完成服务导出的?
- ⾸先Dubbo会将程序员所使⽤的@DubboService注解或@Service注解进⾏解析得到程序员所定义的服务参数,包括定义的服务名、服务接⼝、服务超时时间、服务协议等等,得到⼀个ServiceBean。
- 然后调⽤ServiceBean的export⽅法进⾏服务导出
- 然后将服务信息注册到注册中⼼,如果有多个协议,多个注册中⼼,那就将服务按单个协议,单个注册中⼼进⾏注册
- 将服务信息注册到注册中⼼后,还会绑定⼀些监听器,监听动态配置中⼼的变更
- 还会根据服务协议启动对应的Web服务器或⽹络框架,⽐如Tomcat、Netty等
四、Dubbo是如何完成服务引⼊的?
- 当程序员使⽤@Reference注解来引⼊⼀个服务时,Dubbo会将注解和服务的信息解析出来,得到当前所引⽤的服务名、服务接⼝是什么
- 然后从注册中⼼进⾏查询服务信息,得到服务的提供者信息,并存在消费端的服务⽬录中
- 并绑定⼀些监听器⽤来监听动态配置中⼼的变更
- 然后根据查询得到的服务提供者信息⽣成⼀个服务接⼝的代理对象,并放⼊Spring容器中作为Bean
五、Dubbo的架构设计是怎样的?
Dubbo中的架构设计是⾮常优秀的,分为了很多层次,并且每层都是可以扩展的,⽐如:
- Proxy服务代理层,⽀持JDK动态代理、javassist等代理机制
- Registry注册中⼼层,⽀持Zookeeper、Redis等作为注册中⼼
- Protocol远程调⽤层,⽀持Dubbo、Http等调⽤协议
- Transport⽹络传输层,⽀持netty、mina等⽹络传输框架
- Serialize数据序列化层,⽀持JSON、Hessian等序列化机制
各层说明
● config 配置层:对外配置接⼝,以 ServiceConfig , ReferenceConfig 为中⼼,可以直接初
始化配置类,也可以通过 spring 解析配置⽣成配置类
● proxy 服务代理层:服务接⼝透明代理,⽣成服务的客户端 Stub 和服务器端 Skeleton, 以
ServiceProxy 为中⼼,扩展接⼝为 ProxyFactory
● registry 注册中⼼层:封装服务地址的注册与发现,以服务 URL 为中⼼,扩展接⼝为
RegistryFactory , Registry , RegistryService
● cluster 路由层:封装多个提供者的路由及负载均衡,并桥接注册中⼼,以 Invoker 为中⼼,扩
展接⼝为 Cluster , Directory , Router , LoadBalance
● monitor 监控层:RPC 调⽤次数和调⽤时间监控,以 Statistics 为中⼼,扩展接⼝为
MonitorFactory , Monitor , MonitorService
● protocol 远程调⽤层:封装 RPC 调⽤,以 Invocation , Result 为中⼼,扩展接⼝为
Protocol , Invoker , Exporter
● exchange 信息交换层:封装请求响应模式,同步转异步,以 Request , Response 为中⼼,扩
展接⼝为 Exchanger , ExchangeChannel , ExchangeClient , ExchangeServer
● transport ⽹络传输层:抽象 mina 和 netty 为统⼀接⼝,以 Message 为中⼼,扩展接⼝为
Channel , Transporter , Client , Server , Codec
● serialize 数据序列化层:可复⽤的⼀些⼯具,扩展接⼝为 Serialization , ObjectInput ,
ObjectOutput , ThreadPool
关系说明
- 图中的 Consumer 和 Provider 是抽象概念,只是想让看图者更直观的了解哪些类分属于客户端与 服务器端,不⽤ Client 和 Server 的原因是 Dubbo 在很多场景下都使⽤ Provider, Consumer, Registry, Monitor 划分逻辑拓普节点,保持统⼀概念。
- ⽽ Cluster 是外围概念,所以 Cluster 的⽬的是将多个 Invoker 伪装成⼀个 Invoker,这样其它⼈只要关注 Protocol 层 Invoker 即可,加上 Cluster 或者去掉 Cluster 对其它层都不会造成影响,因为只有⼀个提供者时,是不需要 Cluster 的。
- Proxy 层封装了所有接⼝的透明化代理,⽽在其它层都以 Invoker 为中⼼,只有到了暴露给⽤户使⽤时,才⽤ Proxy 将 Invoker 转成接⼝,或将接⼝实现转成 Invoker,也就是去掉 Proxy 层 RPC是可以 Run 的,只是不那么透明,不那么看起来像调本地服务⼀样调远程服务。
- ⽽ Remoting 实现是 Dubbo 协议的实现,如果你选择 RMI 协议,整个 Remoting 都不会⽤上,Remoting 内部再划为 Transport 传输层和 Exchange 信息交换层,Transport 层只负责单向消息传输,是对 Mina, Netty, Grizzly 的抽象,它也可以扩展 UDP 传输,⽽ Exchange 层是在传输层之上封装了 Request-Response 语义。
- Registry 和 Monitor 实际上不算⼀层,⽽是⼀个独⽴的节点,只是为了全局概览,⽤层的⽅式画在⼀起。
六、Dubbo服务之间的调用是阻塞的吗?
默认是同步等待结果阻塞的,支持异步调用
Dubbo 是基于 IO 的非阻塞实现并行调用,客户端不需要启动多线程即可完成并行调用多个远程服务,相对多线程开销较小,异步调用会返回一个 Future 对象
异步调用流程图如下: