从零手写RPC
2017-12-04 11:52
218 查看
RPC概述
RPC(Remote Proceduce Call 远程过程调用) 一般用来实现部署在不同机器上的系统之间的方法调用,使程序能够像访问本地系统资源一样,通过网络传输过去访问远端系统资源。RPC 调用过程
Client 客户端调用方法实现,负责发起RPC调用。
ClientStub/SereverStub 可以看作一个代理对象,屏蔽RPC调用过程中复杂的网络处理逻辑,使RPC透明化,使得调用远程方法想调用本地方法一样。
Server 服务端提供远程服务。
Stub 主要作用
* 序列化:负责数据的序列化发序列化。
* 网络传输:数据发送与接收。
注:ServerStub又叫Skeleton。
RPC 实现
1. 远程服务接口
public interface IHello { public String sayHello(String info); }
2. 远程服务接口实现类(Server)
public class HelloService implements IHello { public String sayHello(String info) { String result = "hello : " + info; System.out.println(result); return result; } }
提供服务实现的类。
3.服务器代理实现(Skeleton)
public class RpcProxyServer { private IHello hello = new HelloService(); public void publisherServer(int port) { try (ServerSocket ss = new ServerSocket(port)) { while (true) { try (Socket socket = ss.accept()) { try (ObjectInputStream ois = new ObjectInputStream(socket.getInputStream())) { String method = ois.readUTF(); Object[] objs = (Object[]) ois.readObject(); Class<?>[] types = new Class[objs.length]; for (int i = 0; i < types.length; i++) { types[i] = objs[i].getClass(); } Method m = HelloService.class.getMethod(method, types); Object obj = m.invoke(hello, objs); try (ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream())) { oos.writeObject(obj); oos.flush(); } } } catch (Exception e) { e.printStackTrace(); } } } catch (Exception e) { e.printStackTrace(); } } }
构建一个ServerSocket服务监听来自客户端的请求。
接收请求的数据。(方法名和参数)
根据请求的数据(方法名和参数),使用反射调用相应的服务。
输出服务的响应数据。
4. RPC 客户端代理实现(ClientStub)
public class RpcProxyClient<T> { public T proxyClient(Class<T> clazz) { return (T) clazz.cast(Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try (Socket socket = new Socket("localhost", 8000)) { try (ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream())) { oos.writeUTF(method.getName()); oos.writeObject(args); oos.flush(); try (ObjectInputStream ois = new ObjectInputStream(socket.getInputStream())) { return ois.readObject(); } } } } })); } }
构建一个Socket,连接远程服务。
向远程服务发送数据。(方法名和方法参数)
接收远程服务响应的数据。
5.服务端发布服务
public class RpcServer { //发布服务 public static void main(String[] args) { RpcProxyServer server = new RpcProxyServer(); server.publisherServer(8000); } }
6.客户端调用(Client)
public class RpcClient { // 调用服务 public static void main(String[] args) { RpcProxyClient<HelloService> rpcClient = new RpcProxyClient<>(); IHello hello = rpcClient.proxyClient(HelloService.class); String s = hello.sayHello("dd"); System.out.println(s); } }
想了解更多精彩内容请关注我的公众号
本人简书blog地址:http://www.jianshu.com/u/1f0067e24ff8
点击这里快速进入简书
GIT地址:http://git.oschina.net/brucekankan/
点击这里快速进入GIT
相关文章推荐
- Java分布式组件 - - RPC(手写一个RPC)
- 手写一个简单的RPC
- Java手写Ajax
- RPC框架性能基本比较测试
- 解决 LNK1318 Unexpected PDB error; RPC (23) 问题
- web service与远程调用(RPC)的区别
- 手写数字识别
- protobuf + grpc 使用入门 二
- RPC的应用
- 深入Protobuf源码-Descriptor、Message、RPC框架
- 用CppCMS实现web site并同时支持json_rpc服务
- RabbitMQ 实现RPC
- hadoop------RPC的Server
- 【Android】灵云手写离线识别使用说明
- WPF4.0用tablet实现手写输入(更新XP SP3下也能手写输入方法)
- mount 错误 “RPC: failed to contact local rpcbind server (errno 5)
- 分布式文件系统KFS源码阅读与分析(三):RPC实现机制(MetaServer端)
- Cannot register service: RPC: Unable to receive; errno = Connection refused
- hadoop IPC/RPC 机制
- 简单的RPC原型与实现原理