面试官会问到这个问题,主要考察
- 你有没有对某个rpc框架原理有深入了解
考察你能不能从整体上来思考一下,如何设计一个rpc框架,考察系统设计能力。
参考答案
遇到这类问题,从了解的类似框架原理入手,说说参照dubbo的原理,来设计rpc,比如说dubbo的分层,每个层的功能等来进行剖析。
从注册中心开始,需要有一个注册中心,保留各个服务的信息,一般可以参考zk
- 服务消费者需要去注册中心获取对应服务信息,每个服务可能会存在于多台机器上(集群上)
- 基于动态代理,发起一次请求。面向接口获取到一个动态代理,这个动态代理就是接口在本地的一个代理,之后,这个代理会找到服务对应的机器地址。
- 找到哪个机器发送请求,需要有个负载均衡算法。(几种负载均衡策略简单说一下)
- 接着找到一台机器,就可以跟他发送请求,用什么发送呢?可以使用Java中的netty框架,nio方式等。发送什么格式的数据呢?(序列化呗)可以使用hessian序列化协议,或者是别的。
- 服务器那边一样的问题,需要针对自己的服务生成一个动态代理,监听某个网络端口,然后代理本地的服务代码,接受到请求的时候,调用对应的服务代码。
dubbo的架构
在来回顾一下dubbo的架构。首先,从github上clone下来dubbo项目,根据其中子项目的名称,其实就可以判断出各个模块的作用。
dubbo-common
公共逻辑子项目,定义各个子项目中通用的组件和工具类,如:io,日志,配置处理等dubbo-rpc
分布式协调服务框架核心,该模块定义了RPC相关的组件,包括服务发布,服务调用代理,远程调用结果,rpc调用网络协议,rpc调用监听器和过滤器等等。该模块提供了默认的基于dubbo协议的实现,还提供了hessian,http,rmi以及webservice等协议实现,能够满足绝大多数项目的使用需求,另外还提供了对自定义协议的扩展。dubbo-registry
注册中心子项目,它是RPC中consumer服务消费者和provider服务提供者两个重要角色的协调者,该子项目定义了核心的注册中心组件,提供了mutilcast,redis和zookeeper的功能多种注册中心实现,用于不同的使用场景,大部分项目会选择使用zk做注册中心。dubbo-remoting
远程通讯子项目,RPC的实现基础就是远程通讯,consumer要调用provider的远程方法必须是通过远程通讯实现的。该模块定义了远程传输器,endpoint终端,客户端,服务端,编码解码器,数据交换,缓冲区,通讯异常定义等组件。他是对于远程网络通讯的抽象,提供了诸如netty,mina,http等协议和技术框架的实现。dubbo-monitor
监控子项目,该模块可以监控服务调用的各种信息,例如调用耗时,调用量,调用结果等。监控中心在调用过程中收集调用信息,发送到监控服务,在监控服务中可以存储这些信息,对这些数据进行统计分析和展示。dubbo默认提供了一个实现,该实现非常简单,只是作为默认的实现范例,生产环境使用价值不高,往往需要自己去实现。dubbo-container
容器子项目,是一个独立容器,以简单的Main(类)加载Spring启动,因为服务通常不需要Tomcat/Jboss等web容器的特性,没必要用web容器去加载服务。
dubbo-config
配置中心子项目,该模块通过配置信息,将dubbo组件的各个模块整合在一起,给框架的使用者提供可配置,方便使用的分布式服务框架,定义了面向dubbo使用者的各种信息配置,例如服务发布配置,方法发布配置,服务消费配置,应用程序配置,注册中心配置,协议配置,监控配置等等。
dubbo-cluster
集群子项目,将多个服务提供方伪装成一个提供方,包括:负载均衡,容错,路由等,集群的地址列表可以是静态的,可以是注册中心下发。
dubbo-admin
web应用,可以独立部署,用于管理dubbo服务,该管理应用可以连接注册中心,读取和更新注册中心的内容。
实现原理
角色和运行原理
一个dubbo项目的角色主要分为以下5种
- Provider 服务提供方
- Consumer 服务消费者
- Registry:注册中心
- Container 服务运行容器
- Monitor 监控中心
工作原理
- 服务导出:服务提供方导出服务,监听服务端口
- 服务注册:服务提供方 注册服务信息到注册中心
- 服务订阅:服务消费方,订阅关注的服务
- 服务发现:当服务地址发生变更时,注册中心通知服务消费端
- 远程服务调用:根据负载均衡策略,选择服务地址,直接调用
- 监控:监控器 收集和展示 服务提供方,服务消费方之间的服务调用统计信息。
