最简RPC框架实现
2018-02-04 10:56
309 查看
【博文总目录>>>】|【项目源码>>>】
RPC概述
RPC(Remote Proceduce Call 远程过程调用) 一般用来实现部署在不同机器上的系统之间的方法调用,使程序能够像访问本地系统资源一样,通过网络传输过去访问远端系统资源。RPC 调用过程
1、Client 客户端调用方法实现,负责发起RPC调用。
2、ClientStub/SereverStub 可以看作一个代理对象,屏蔽RPC调用过程中复杂的网络处理逻辑,使RPC透明化,使得调用远程方法想调用本地方法一样。
3、Server 服务端提供远程服务。
Stub 主要作用 序列化:负责数据的序列化发序列化。 网络传输:数据发送与接收。 注:ServerStub又叫Skeleton。
RPC 实现
远程服务接口
package mongo.rpc.service.api; /** * Author: 王俊超 * Date: 2018-02-04 10:09 * Blog: http://blog.csdn.net/derrantcm * Github: https://github.com/wang-jun-chao * All Rights Reserved !!! */ public interface IHello { public String sayHello(String info); }
远程服务接口实现类(Server)
package mongo.rpc.service.impl; import mongo.rpc.service.api.IHello; /** * Author: 王俊超 * Date: 2018-02-04 10:09 * Blog: http://blog.csdn.net/derrantcm * Github: https://github.com/wang-jun-chao * All Rights Reserved !!! */ public class HelloServiceImpl implements IHello { public String sayHello(String info) { String result = "hello : " + info; System.out.println(result); return result; } }
3.服务器代理实现(Skeleton)
构建一个ServerSocket服务监听来自客户端的请求。接收请求的数据。(方法名和参数)
根据请求的数据(方法名和参数),使用反射调用相应的服务。
输出服务的响应数据。
package mongo.rpc.server; import mongo.rpc.service.api.IHello; import mongo.rpc.service.impl.HelloServiceImpl; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.lang.reflect.Method; import java.net.ServerSocket; import java.net.Socket; /** * 代理服务器,用于从执行代理客户端发送过来的请求 * Author: 王俊超 * Date: 2018-02-04 10:10 * Blog: http://blog.csdn.net/derrantcm * Github: https://github.com/wang-jun-chao * All Rights Reserved !!! */ public class RpcProxyServer { private IHello hello = new HelloServiceImpl(); /** * 启动代理服务器 * @param port */ 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 = HelloServiceImpl.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(); } } }
RPC 客户端代理实现(ClientStub)
构建一个Socket,连接远程服务。向远程服务发送数据。(方法名和方法参数)
接收远程服务响应的数据。
package mongo.rpc.client; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.net.Socket; /** * 代理客户端,用于从服务获取调用结果 * Author: 王俊超 * Date: 2018-02-04 10:12 * Blog: http://blog.csdn.net/derrantcm * Github: https://github.com/wang-jun-chao * All Rights Reserved !!! */ public class RpcProxyClient { /** * 创建代理对象 * * @param clazz 要进行代理的接口 * @param host 服务器所在的地址 * @param port 服务器所提供的端口 * @param <T> 接口类 * @return 接口的代理对象 */ public <T> T proxyClient(Class<T> clazz, String host, int port) { return (T) clazz.cast(Proxy.newProxyInstance(clazz.getClassLoader(), new Class[]{clazz}, new InvocationHandler() { /** * 代理方法调用,用于从服务端获取调用结果 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try (Socket socket = new Socket(host, port)) { 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(); } } } } })); } }
服务端发布服务
package mongo.rpc; import mongo.rpc.server.RpcProxyServer; /** * Author: 王俊超 * Date: 2018-02-04 10:13 * Blog: http://blog.csdn.net/derrantcm * Github: https://github.com/wang-jun-chao * All Rights Reserved !!! */ public class RpcServer { //发布服务 public static void main(String[] args) { RpcProxyServer server = new RpcProxyServer(); server.publisherServer(9999); } }
客户端调用(Client)
package mongo.rpc; import mongo.rpc.client.RpcProxyClient; import mongo.rpc.service.api.IHello; /** * Author: 王俊超 * Date: 2018-02-04 10:14 * Blog: http://blog.csdn.net/derrantcm * Github: https://github.com/wang-jun-chao * All Rights Reserved !!! */ public class RpcClient { // 调用服务 public static void main(String[] args) { RpcProxyClient rpcClient = new RpcProxyClient(); IHello hello = rpcClient.proxyClient(IHello.class, "localhost", 9999); String s = hello.sayHello("welcome to rpc"); System.out.println(s); } }
运行结果
相关文章推荐
- RPC框架实现思路浅析
- Java开发大型互联网RPC框架 Dubbo 实现原理之Dubbo实战
- 一个简单的rpc框架实现(一)
- 一起写RPC框架(十五)RPC注册中心二--注册中心的基本实现
- 基于Netty的RPC简单框架实现(五):功能测试与性能测试
- 一个简单RPC框架是如何炼成的(III)——实现带参数的RPC调用
- 一个简单RPC框架是如何炼成的(IV)——实现RPC消息的编解码
- 基于Netty的RPC简单框架实现(一):RPC客户端
- rpc框架yar之源码解析- 打包的实现
- 最简单的Rpc框架的实现
- 基于Netty的RPC简单框架实现(二):RPC服务端
- [读书笔记]深入解析MapReduce架构设计与实现原理——CH4 Hadoop RPC基本框架
- Java实现简单的RPC框架
- RPC框架实现思路浅析
- TCP-IP学习笔记八:RPC(Netty和Spring)实现webServer框架
- 【原创】自己动手实现RPC服务调用框架
- 分布式学习笔记1通过Java自己实现简单的HTTP RPC框架
- Netty+Zookeeper实现一个类似Dubbo的RPC框架
- 一个分布式rpc框架的实现方案(二)
- 一个简单的rpc框架的实现