一、一个RPC的核心功能包括5个部分。

      客户端、客户端stub、网络传输模块、服务端stub、服务端。

     (1)客户端:服务调用方。

     (2)客户端存根(client stub):存放服务端地址,将客户端请求数据转化为网络信息,通过网络传输发给服务端。

     (3)服务端存根(server stub):接受客户端发来的网络数据,并进行解析。然后调用本地服务进行处理。

     (4)服务端:服务提供方。

     (5)网络传输模块:TCP或者HTTP。

二、一次RPC调用流程如下:

     (1)客户端通过本地调用方式调用服务。

     (2)客户端Stub接收调用请求后将相关数据信息序列化,转换成可以进行网络传输的消息体。

     (3)客户端Stub找到远程的服务地址,并且将消息通过网络发给服务端。

     (4)服务端Stub收到消息后进行解码(反序列化操作)。

     (5)服务端Stub根据解码结果调用本地的服务进行相关处理。

     (6)服务端本地服务业务处理。

     (7)处理结果返回给服务端Stub。

     (8)服务端Stub序列化结果,并通过网络发送给客户端Stub。

     (9)客户端Stub接收到消息,并进行解码(反序列化)。

     (10)客户端得到结果。

三、RPC核心模块的功能实现

       主要实现三个技术点:服务寻址、数据流的序列化于反序列化、网络传输。

      (1)服务寻址

       在RPC中,所有函数必须有自己的ID,这个ID在所有进程中唯一确定。客户端在进行远程过程调用时,必须附上这个ID,

然后需要在客户端和服务端分别维护一个函数和Call ID的对应表。客户端要调用服务端的某个函数时,就查询这个对应表,找出

相应的CalI ID,然后传给服务端。服务端接受信息后,找到客户端需要调用的函数,执行相关代码。

       实现方法:服务注册中心。

       实现案例:RMI(Remote Method Invocation,远程方法调用)RPC的本身实现方法。Registry(服务发现):借助JNDI发布并调用的RMI服务。JNDI是一个注册表,服务端将服务对象放入注册表中,客户端从注册表中获取服务对象。RMI服务在服务端实现之后需要注册到RMI Server上,然后客户端从指定的RMI地址上Lookup服务,调用该服务对应的方法即可完成远程过程调用。

      (2)序列化于反序列化

       在远程过程调用时,客户端和服务端是不同的进程,不能通过内存来传递参数,需要将客户端的请求转化成一个字节流,传递给服务端之后,服务段把字节流转化成自己能读取的格式。

       只有二进制的数据才能在网络中传输,序列化和反序列化的定义是:

       将对象转化成二进制流的过程叫做序列化,将二进制流转化成对象的过程叫做反序列化。

      (3)网络传输

       网络传输层需要把Call ID和序列化后的参数字节流传给服务端,然后再把序列化之后的结果传回客户端。大部分RPC框架都使用了TCP协议,gRPC使用了HTTP2。

       TCP连接可以是按需连接,也可以长连接,多个远程过程调用共享同一个连接。

 

 

参考:https://developer.51cto.com/art/201906/597963.htm