一、一个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