RPC 是什么

RPC( Remote Procedure Call),RPC 是一种技术思想,并不是某种技术架构。我的理解是,基于 RPC 思想产生了很多不同类型的框架,例如 Zookeeper,Dubbo,RocketMQ 应用内部的通信方式,都是用到了 RPC 的思想。RPC 意思是远程方法调用,即通过网络调用远程服务的过程

RPC 的基本组成部分

协议

序列化

动态代理

为什么说的那么简单?

实现 Demo 千千万,不如自己写一个感受一下

先看图

POM 相关依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.rpc</groupId>
    <artifactId>rpc</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.reflections</groupId>
            <artifactId>reflections</artifactId>
            <version>0.9.10</version>
        </dependency>
    </dependencies>
</project>

Request 对象

package com.client.user.pojo;
import java.io.Serializable;

// 序列化请求对象
public class RpcRequest implements Serializable {
    private static final long  serialVersionUID = 1L;

    // 包名
    private String className;

    // 方法名
    private String methodName;

    // 请求方法类型
    private Class<?>[] paramTypes;

    // 请求的参数值
    private Object[] params;

    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<?>[] getParamTypes() {
        return paramTypes;
    }
    public void setParamTypes(Class<?>[] paramTypes) {
        this.paramTypes = paramTypes;
    }
    public Object[] getParams() {
        return params;
    }
    public void setParams(Object[] params) {
        this.params = params;
    }

}

Client

package com.client.user;

public interface UserInfo {
    void getUser();
}
package com.client.user;

public class UserInfoImpl implements UserInfo{


    public void getUser() {
        System.out.println("调用成功");
    }
}
package com.client.util;

import com.client.user.UserInfo;
import com.client.user.pojo.RpcRequest;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ApiProxy implements InvocationHandler{

    public <T> T getProxy(Class<T> clazz){
        // clazz 不是接口不能使用JDK动态代理
        return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class<?>[]{ clazz }, this);
    }

    /**
     * proxy 代理类代理真是代理对象com.sun.proxy.%Proxy0
     * method 要调用的方法
     * args 代理对象要传递的参数
     * */
    public Object invoke(Object proxy, Method method, Object[] args)  {

        // 序列化class,method,类型,参数
        RpcRequest rpcRequest = new RpcRequest();
        rpcRequest.setClassName(method.getDeclaringClass().getName());
        rpcRequest.setMethodName(method.getName());
        rpcRequest.setParamTypes(method.getParameterTypes());
        rpcRequest.setParams(args);

        // 发送socket
        Client client = new Client();
        int port = 12345;
        String host = "127.0.0.1";
        client.sendSocket(rpcRequest, host, port);
        return null;
    }

    public static void main(String[] args) {
        ApiProxy apiProxy = new ApiProxy();
        UserInfo proxy = apiProxy.getProxy(UserInfo.class);
        proxy.getUser();
    }
}
package com.client.util;

import com.client.user.pojo.RpcRequest;

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;

public class Client {

    public void sendSocket(RpcRequest rpcRequest,String host, int port){

        Socket socket = null;
        try {
            socket = new Socket(host, port);
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
            objectOutputStream.writeObject(rpcRequest);

            objectOutputStream.flush();
//            objectOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

Server

package com.server;

import com.client.user.pojo.RpcRequest;
import org.reflections.Reflections;

import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.*;

public class Server {

    public Socket clientSocket;

    public void runServer() throws Exception {
        ServerSocket serverSocket = new ServerSocket(12345);
        RpcRequest  request;

        while (true){
            Socket accept = serverSocket.accept();
            ObjectInputStream objectInputStream = new ObjectInputStream(accept.getInputStream());
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(accept.getOutputStream());
            Object param = objectInputStream.readObject();
            request = (RpcRequest)param;


            Class clazz = Class.forName(request.getClassName());
            Reflections reflections = new Reflections("com.client.user");

            Set<Class> implClassSet = reflections.getSubTypesOf(clazz);

            Class[] classeses = implClassSet.toArray(new Class[0]);
            String classImpl = classeses[0].getName();

            Class<?> aClass = Class.forName(classImpl);
            Constructor<?> constructor = aClass.getConstructor();
            Object o = constructor.newInstance();
            Method method = o.getClass().getMethod(request.getMethodName(),request.getParamTypes());
            method.invoke(o,request.getParams());

            accept.close();
            objectInputStream.close();
            objectOutputStream.close();
        }

    }

    public static void main(String[] args) throws Exception {
        Server server = new Server();
        server.runServer();
    }
}

结果

小结一下


↙↙↙阅读原文可查看相关链接,并与作者交流