RPC框架原理

RPC协议

RPC(Remote Procedure Call)远程过程调用,是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。用来实现部署在不同机器上的的系统之间的方法调用,使得程序能够像访问本地方法一样,通过网络传输去访问远程系统资源。

手写RPC简单框架

rpc-server:rpc服务端,包含两个模块rpc-server-api、rpc-server-provider

rpc-client:rpc客户端

rpc-server-api

public interface IHelloService {
    String sayHello(String name);
}

/**
 * 封装RPC客户端向客户端发送的参数
 */
public class RpcRequest implements Serializable {
    private String className;
    private String methodName;
    private Class[] types;
    private Object[] parameters;

    public String getClassName() { return className; }
    public void setClassName(String className) { this.className = className; }
    public String getMethodName() { return methodName; }
    public void setMethodName(String methodName) { this.methodName = methodName; }
    public Class[] getTypes() { return types; }
    public void setTypes(Class[] types) { this.types = types; }
    public Object[] getParameters() { return parameters; }
    public void setParameters(Object[] parameters) { this.parameters = parameters; }
}

rpc-server-provider

首先在pom.xml中引入rpc-server-api依赖

public class HelloServiceImpl implements IHelloService {
    @Override
    public String sayHello(String name) {
        return "Hello, I am " + name;
    }
}

public class RpcProxyServer {
    public void publisher(final Object service, int host) {
        try {
            ExecutorService executorService = Executors.newCachedThreadPool();
            ServerSocket serverSocket = new ServerSocket(host);
            while (true) {
                final Socket socket = serverSocket.accept();
                executorService.submit(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
                            RpcRequest rpcRequest = (RpcRequest) objectInputStream.readObject();
                            Class<?> clazz = Class.forName(rpcRequest.getClassName());
                            Method method = clazz.getMethod(rpcRequest.getMethodName(), rpcRequest.getTypes());
                            Object result = method.invoke(service, rpcRequest.getParameters());
                            ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
                            objectOutputStream.writeObject(result);
                            objectOutputStream.flush();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

public class App {
    public static void main( String[] args ) {
        IHelloService helloService = new HelloServiceImpl();
        RpcProxyServer rpcProxyServer = new RpcProxyServer();
        // 发布服务
        rpcProxyServer.publisher(helloService, 8888);
    }
}

rpc-client

// 动态代理
public class RpcProxyClient {
    public <T> T clientProxy(Class<T> interfaceClass, String host, int port) {
        return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class<?>[] {interfaceClass}, new RemoteInvocationHandler(host, port));
    }
}

public class RemoteInvocationHandler implements InvocationHandler {
    private String host;
    private int port;

    public RemoteInvocationHandler(String host, int port) {
        this.host = host;
        this.port = port;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        RpcRequest rpcRequest = new RpcRequest();
        rpcRequest.setClassName(method.getDeclaringClass().getName());
        rpcRequest.setMethodName(method.getName());
        rpcRequest.setTypes(method.getParameterTypes());
        rpcRequest.setParameters(args);
        Socket socket = new Socket(host, port);
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
        objectOutputStream.writeObject(rpcRequest);
        objectOutputStream.flush();
        ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
        Object object = objectInputStream.readObject();
        return object;
    }
}

public class App {
    public static void main( String[] args ) {
        RpcProxyClient client = new RpcProxyClient();
        IHelloService helloService = client.clientProxy(IHelloService.class, "localhost", 8888);
        // 客户端收到服务端返回结果
        String content = helloService.sayHello("Lucifer");
        System.out.println(content);
    }
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值