这篇文章介绍了一个难度适中的定制化RPC项目应该实现哪些功能,并且深入回答了RPC框架在面试过程中容易被问到的一些问题,看完这一整篇文章,相信Java初学者会对RPC项目有更深的了解。如果文章中有哪些错误,欢迎批评指正,谢谢。
1、我们要做一个什么样的RPC项目
1.1 RPC概述
RPC 的主要功能目标是让构建分布式计算(应用)更容易,在提供强大的远程调用能力时不损失本地调用的语义简洁性。为实现该目标,RPC 框架需提供一种透明调用机制,让使用者不必显式的区分本地调用和远程调用。
RPC的优点:
- 分布式设计
- 部署灵活
- 解耦服务
- 扩展性强
RPC框架优势:
- RPC框架一般使用长链接,不必每次通信都要3次握手,减少网络开销。
- RPC框架一般都有注册中心,有丰富的监控管理、发布、下线接口、动态扩展等,对调用方来说是无感知、统一化的操作、协议私密,安全性较高
- RPC 协议更简单内容更小,效率更高,服务化架构、服务化治理,RPC框架是一个强力的支撑。
- RPC基于TCP实现,也可以基于Http2实现
1.2 主流的RPC框架
主流RPC框架:
- Dubbo:国内最早开源的 RPC 框架,由阿里巴巴公司开发并于 2011 年末对外开源,仅支持 Java 语言。
- Motan:新浪微博内部使用的 RPC 框架,于 2016 年对外开源,仅支持 Java 语言。
- Tars:腾讯内部使用的 RPC 框架,于 2017 年对外开源,仅支持 C++ 语言。
- Spring Cloud:国外 Pivotal 公司 2014 年对外开源的 RPC 框架,提供了丰富的生态组件。
- gRPC:Google 于 2015 年对外开源的跨语言 RPC 框架,支持多种语言。
- Thrift:最初是由 Facebook 开发的内部系统跨语言的 RPC 框架,2007 年贡献给了 Apache 基金,成为 Apache 开源项目之一,支持多种语言。
1.3 我们要做一个实现了什么技术的RPC项目
使用Netty、Spring和Zookeeper实现类似dubbo的分布式RPC项目。采用了JSON作为序列化方式,以自定义Spring注解为基础实现了动态代理,实现了TCP的长链接并支持心跳检测,通过Zookeeper的Watcher机制实现了客户端连接的监控、管理和发现等功能,并实现了服务注册的功能。
1.4 与Dubbo的区别
- 项目只使用netty+spring做服务器,而dubbo的服务器支持tomcat、netty等容器
- 项目的动态代理使用的是spring的动态代理,dubbo则是使用的javassist
- 项目只支持JSON的序列化,dubbo支持的序列化形式更多更全面
2、深入RPC技术
2.1 普遍的RPC框架流程
具体调用过程:
- 服务消费者(client客户端)通过本地调用的方式调用服务
- 客户端存根(client stub)接收到请求后负责将方法、入参等信息序列化(组装)成能够进行网络传输的消息体
- 客户端存根(client stub)找到远程的服务地址,并且将消息通过网络发送给服务端
- 服务端存根(server stub)收到消息后进行解码(反序列化操作)
- 服务端存根(server stub)根据解码结果调用本地的服务进行相关处理
- 本地服务执行具体业务逻辑并将处理结果返回给服务端存根(server stub)
- 服务端存根(server stub)将返回结果重新打包成消息(序列化)并通过网络发送至消费方
- 客户端存根(client stub)接收到消息,并进行解码(反序列化)
- 服务消费方得到最终结果
2.2 该RPC项目的具体调用过程
服务器调用:
- 首先需要启动Zookeeper服务器,然后通过spring启动RPC的server
- 此时Rpc的server会把自己注册到Zookeeper中
- 在Rpc的server启动过程中,会采用ApplicationLi