RPC的原理及其简单实现
什么是RPC
RPC,全称为Remote Procedure Call,即远程过程调用。它的目的是使调用远程服务像调用本地服务一样。
RPC可基于HTTP或TCP协议,Web Service就是基于HTTP协议的RPC,它具有良好的跨平台性,但其性能却不如基于 TCP 协议的 RPC。会两方面会直接影响 RPC 的性能,一是传输方式,二是序列化。
RPC简易架构
RPC可简化为如下架构:
调用步骤为:
- 客户端函数调用客户端句柄,执行传送参数
- 调用本地系统内核发送网络消息
- 消息通过tcp或者自定义协议或者其他协议传送到服务端
- 服务端句柄获取消息及参数
- 执行远程过程
- 将远程过程的结果返回给服务器句柄
- 服务器句柄返回结果,调用远程系统内核发送网络消息
- 本地主机获取返回消息
- 客户端句柄通过内核接受消息
- 客户端接收句柄返回的数据
RPC可按照角色分为3类:
- 服务提供者:由框架提供,运行在服务端,发布服务、接收客户端消息、返回消息
- 服务调用者:由框架提供,运行在客户端,生成代理对象、调用远程服务
- 服务具体实现:由使用框架者提供,运行在服务器,服务接口、接口实现类
RPC简易实现
Server端
Server
在服务端利用Socket监听指定端口,并启用线程池来执行客户端的请求。
注册服务service.registerService(StudentService.class, StudentServiceImpl.class);
1 | public class Server { |
ServerService
ServerService实现了Runnable接口,便于提交给线程池执行
而后从Socket读取数据,转为Request对象
1 | public class ServerService implements Runnable { |
StudentService
1 | public interface StudentService { |
StudentServiceImpl
StudentServiceImpl是StudentService的实现类
1 | public class StudentServiceImpl implements StudentService { |
Client端
SocketClient
1 | public class SocketClient { |
SocketClientProxy
SocketClientProxy创建代理对象,拦截代理对象执行方法
1 | public class SocketClientProxy { |
公共
Request
1 | public class Request implements Serializable { |
Response
1 | public class Response implements Serializable { |
Student
1 | public class Student implements Serializable { |
测试代码
1 | public class Test { |
RMI实现简易RPC
定义RMI对外服务接口HelloService
HelloService
1 | public interface HelloService extends Remote { |
RMI接口方法定义必须显式声明抛出RemoteException异常
HelloServiceImpl
服务端接口实现HelloServiceImpl
1 | public class HelloServiceImpl extends UnicastRemoteObject implements HelloService { |
服务端方法实现必须继承UnicastRemoteObject类,该类定义了服务调用方法与服务提供方对象实例,并建立一对一连接。
ServerMain
服务端RMI服务启动代码
1 | public class ServerMain { |
ClientMain
客户端远程调用RMI服务代码
1 | public class ClientMain { |