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);
}
}