从零手写RPC
RPC概述
RPC(Remote Proceduce Call 遠程過程調用) 一般用來實現部署在不同機器上的系統之間的方法調用,使程序能夠像訪問本地系統資源一樣,通過網絡傳輸過去訪問遠端系統資源。
RPC 調用過程
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();}} }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() {@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();}}}}}));} }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 进阶之路》 下--推荐书籍
- 下一篇: 从零手写IOC