【RPC】手写RPC框架

RPC流程

  1. 客户端处理过程中 调用 Client stub(就像调用本地方法一样),传递参数;
  2. Client stub 将参数 编组 为消息,然后通过系统调用向服务端发送消息;
  3. 客户端本地操作系统将消息从客户端机器 发送 到服务端机器;
  4. 服务端操作系统将接收到的数据包 传递 给Server stub;
  5. Server stub 解组 消息为参数;
  6. Server stub 再 调用 服务端的过程,过程执行结果以反方向的相同步骤相应给客户端。

我们的目的是要实现上面 RPC 的各个流程

从使用者角度思考

用户使用RPC框架开发过程时需要做什么?

  1. 定义过程 定义接口
  2. 服务端实现过程
  3. 客户端使用生成的stub代理对象

设计客户端

代理对象

客户端如何生成过程接口的代理对象?
答案是设计客户端代理工厂,用JDK动态代理即可生成接口的代理对象。

由 ClientStubProxyFactory 获得代理对象,代理对象要完成消息的编组、发送、结果响应后的解组过程,那么在JDK动态代理里面必须用到 InvocationHandler,具体的过程由 ClientStubInvocationHandler 来实现。

  • ClientStubInvocationHandler 中需要完成哪些事情?
    1. 编组消息
    2. 发送网络请求
  • 将请求的内容编组为消息由谁来做?
    1. 由消息协议层来完成
    2. 由网络层发送请求
  • 消息协议是固定的吗?它与什么有关?
    1. 看框架对协议的支持广度,如果支持多种协议,就是会灵活变化的,它与具体的服务相关,A服务提供者可能选用的是协议1,B服务提供者可能选用协议2
  • 客户端怎么知道某服务是用的什么消息协议?
    1. 从获取到的服务信息中来,因此需要一个服务信息发现者
    2. 需要把发现者设计出来,要求:可灵活支持多种发现机制

发现者

由 ServiceInfoDiscoverer 来发现服务,给他一个服务名称,返回服务列表,因为某服务的提供者可能有多个,所以这里要是列表。
ServiceInfo 定义服务的信息,有服务的名称、服务使用的协议。
我们设计多种发现方式,可以基于本地配置文件发现(LocalConfigServiceInfoDiscoverer):将服务提供者的信息放在配置文件,通过加载配置文件来发现;也可以基于ZooKeeper做服务信息的发现(ZookeeperServiceInfoDiscoverer)。

协议层

我们想要做到可以支持多种协议,我们的类该如何设计?
答案是:面向接口编程,使用策略模式、组合

我们定义一个消息协议接口(MessageProtocol),里面包含了编组、解组相关的接口,然后提供各种实现,比如基于JSON、HTTP、Java序列化等等来做消息的传输。

继续看下面的问题:
编组和解组方法该定义怎样的参数与返回值?
编组、解组的操作对象是请求、响应,请求、响应的内容是不同的,编组、解组两个方法是否满足?

定义框架标准的请求、响应类

将协议层方法扩展为4个

网络发送、接受需要在编组时转换为字节,同样接受时也接受字节

网络层

网络层的工作是什么?
发送请求,获得响应。要发起网络请求,则需要知道服务地址。

所以我们在服务信息中添加一个服务地址的属性,然后定义一个 NetClient 作为网络层,

完整类图

不同的颜色代表不同层

服务端

客户端请求过来了,服务端首先需要通过RPCServer接受请求。

在RPCServer中开启网络服务

RPCServer 接收到客户端请求后,需要做哪些工作?

网络层在RPCServer中提供多线程来处理请求,消息协议层复用客户端设计的。
设计一个请求处理类,来完成网络层以上的事。

RPCServer接收到请求后,将请求交给RequestHandler来处理,RequestHandler调用协议层来解组请求消息为Request对象,然后调用过程。

  • RequestHandler如何得到过程对象?
    通过Request中的参数
  • Request中有什么?
    服务名、方法名、参数类型、参数值
  • 是否需要一个过程注册模块?
    是的

过程注册模块:让用户将他们的过程注册到RPC框架中来。
过程暴露模块:想对外发布(暴露)服务
注册和暴露可以由同一个类实现。

最终:

  1. RPCServer中实现网络层:Netty,使用RequestHandler。
  2. serviceRegister模块实现服务注册、发布。
  3. RequestHandler中实现消息协议处理、过程调用。

代码等有空上传。。。

# 分布式 

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×