从零手写RPC

RPC概述

RPC(Remote Proceduce Call 远程过程调用) 一般用来实现部署在不同机器上的系统之间的方法调用,使程序能够像访问本地系统资源一样,通过网络传输过去访问远端系统资源。

RPC 调用过程

  1. Client 客户端调用方法实现,负责发起RPC调用。
  2. ClientStub/SereverStub 可以看作一个代理对象,屏蔽RPC调用过程中复杂的网络处理逻辑,使RPC透明化,使得调用远程方法想调用本地方法一样。
  3. 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();}}
}
  1. 构建一个ServerSocket服务监听来自客户端的请求。
  2. 接收请求的数据。(方法名和参数)
  3. 根据请求的数据(方法名和参数),使用反射调用相应的服务。
  4. 输出服务的响应数据。

4. RPC 客户端代理实现(ClientStub)

public class RpcProxyClient<T> {public T proxyClient(Class clazz) {return (T) clazz.cast(Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), new InvocationHandler() {@Overridepublic 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();}}}}}));}
}
  1. 构建一个Socket,连接远程服务。
  2. 向远程服务发送数据。(方法名和方法参数)
  3. 接收远程服务响应的数据。

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 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


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部