开发 RPC 框架
字数: 0 字 时长: 0 分钟
什么是 RPC ?
RPC (Remote Procedure Call,远程过程调用)是一种计算机通信协议,它允许程序能够像调用本地方法一样调用远程服务器上的方法或函数。
第一次听到 RPC 这个概念的时候是在学习 Kubernetes
的时候,当时官方文档提到底层采用 RPC 进行通信.当时我也不确定 RPC 具体是什么,直到遇到了鱼皮大佬的开源 RPC 项目,才对 RPC 框架有更深的认识,也开始第一次做这种轮子类项目。
项目开源地址:https://gitee.com/ttdxg/t-rpc
效果演示
第一次接触 RPC 概念可能还是很难理解 像调用本地方法一样去调用远程方法 ,下面我演示我开发的 RPC 框架效果:
1. 创建 example-common
模块作为公共的 api
暴露模块,用来暴露接口和实体类
2. 创建 springboot-provider
作为服务提供者,提供接口的具体实现
- 只需要引入
example-common
和roc-starter
模块,在启动类上添加@EnableRpc
注解
- 然后接口实现类上添加
@RpcService
注解表明这是 RPC 接口实现类
3. 创建 springboot-consumer
作为服务消费者,调用服务提供者的接口
- 只需要使用
@RpcReference
注入远程服务,即可当作本地方法一样调用
4. 分别启动服务提供者和消费者,进行测试访问
可以发现 consumer
模块成功访问到了 provider
模块的远程方法
可以发现有了 RPC 框架之后,客户端只需要几个注解就能将远程方法当作本地方法一样进行调用。
框架原理
我们来梳理一下本地调用一个远程方法需要如何实现:
1. 客户端代理
客户端调用 userService.getUser(user)
方法实际是根本不知道userService
接口的getUser
方法的具体实现的。
这里需要代理本地接口,拦截方法调用,封装请求对象
2. 注册中心
客户端代理拦截了方法调用,但是只知道 userService.getUser(user)
(接口、方法名、参数),并不知道实现类在哪里。
那么此时需要去注册中心获取接口的实现类相关信息(服务提供者启动时就需要将提供的服务注册到注册中心)
3. 网络传输
代理通过注册中心知道了服务提供者地址了,此时需要发送请求给服务提供者,请求中需要携带接口、方法名、参数等信息
涉及到网络传输就要考虑通信协议(Http/WebSocket/TCP),而且发送请求涉及到负载均衡策略,确定发送给哪个服务实例。
4. 序列化层
请求参数在网络传输过程中需要序列化,服务提供者收到请求参数后,需要反序列化
5. web 服务器
服务提供者需要选择 Web 服务器用以接收消费者的请求,并根据请求参数选择请求处理器进行处理(找到本地服务实现,再通过网络传输返回结果给消费者)
rpc 远程调用流程
技术选型
鱼皮选择 Etcd(Kubernetes
就是采用 Etcd 作为底层的元数据存储系统)作为注册中心;Vert.x
作为网络框架。
而我本身是为了学习才开发这个 RPC 框架,为了更加深对 Redis
和 Netty
的实战应用,我选择 Redis
来实现注册中心、Netty
作为网络框架。
总之,通过开发这个 RPC 框架,可以对网络、序列化、代理、服务注册与发现、负载均衡、可扩展设计、starter 开发等知识有更深入的理解。
那么接下来就从 0 到 1 开始开发这个 RPC 框架吧!