阅读 144

如何设计一款充满妥协的RPC框架?

如何设计一款充满妥协的RPC框架

什么是RPC

RPC(Remote Procedure Call)即远程方法调用,主要是解决在微服务系统中,不同服务之间的方法调用问题。一般来说调用方只需使用服务提供方所提供的接口即可,剩下的工作需要由RPC框架完成,简单来说RPC框架需要完成以下工作。

  • 网络通信,负责服务提供方与调用方之间的通信
  • 代理接口,需要代理服务提供方所提供方法接口以便让服务调用方可以方便的调用方法
  • 服务调用,根据请求调用服务提供方的方法并将数据返回给服务调用者
  • 服务注册与发现,相当于通讯录功能知道哪些人(服务)可以提供哪些功能

网络通信设计

网络通信我们可以使用HTTP协议或自定义通信协议,个人比较讨厌HTTP协议。因此通信协议,采用TCP协议,并定义数据包的格式如下。

充满着妥协的通信协议

  • 数据包的前四个字节用于标记数据包正文的长度(用于解决TCP粘包、半包的问题)
  • 数据包正文保存着我们要传输的数据

数据序列化格式

数据序列方式有很多选择,为了方便我们还是选择了妥协使用JSON作为我们的序列化格式(还是充满着妥协)

网络通信框架

网络通信框架我们使用netty作为我们的通信框架,并且使用同步非阻塞通信模型,为此我们需要解决这个模型所带来的问题见服务调用章节。(小册有售netty教程)

代理接口

通常来说,服务提供方会发布一个只有接口和POJO类的jar包供服务调用方使用,因此我们的RPC框架需要去代理这些接口,如果需要和spring进行整合,我们还需要将代理后的接口以bean的形式注册到Spring容器中。

妥协的设计方案

client包应该只包含服务提供方要对外暴露的接口以及POJO类
service包含client包中接口的实现类

服务调用

由于我们采用的netty(同步非阻塞),为此我们需要设计一个方案,网络通信模型采用同步非阻塞的方案,但在客户端调用方法返回结果是表现为阻塞的。

阻塞设计方案

阻塞的设计方案

阻塞的设计方案,通常在服务调用方发送给服务提供方调用指令之后需要一直等待直到服务提供方返回数据,这种方案简单清晰明了,且妥协。

同步非阻塞的设计方案

由于采用了同步非阻塞的方式来进行通信,因此我们不可能一直阻塞等待服务提供方返回数据,为了模拟这种阻塞的效果,采用以下设计。

在客户端向服务端发送请求之后,立即返回FutureTask,同时生成事务id将事务和Callable绑定,利用FutureTask的特性我们可以实现阻塞效果。

远程方法调用

返回数据则只需要根据返回的事务id,取到相应Callable设置值,并调用call方法即可。

服务的注册与发现

服务的注册于发现可以理解为手机通讯录功能,即你晓得哪些朋友是作什么的,哪些是工具人,哪些是备胎...

因此只要可以存数据的,理论上都可以用来做服务的发现与注册,不论是redis,mysql,zookeeper或自己实现都是可以的。

总结

总得来说,这个RPC框架浑身上下都写着两个字妥协,就管它叫TuoXieRpc.

关注下面的标签,发现更多相似文章
评论