实现一个简易RPC框架,通过动态代理、Socket通信、序列化和反射机制,使客户端像调用本地方法一样调用远程服务。1. 定义公共接口HelloService及数据传输对象RpcRequest和RpcResponse;2. 服务端使用ServerSocket监听请求,接收后通过反射调用本地方法并返回结果;3. 客户端通过JDK动态代理拦截方法调用,封装为RpcRequest发送至服务端;4. 服务端执行方法后将结果封装为RpcResponse返回;5. 测试时先启动服务端绑定8888端口,客户端通过代理发起远程调用并输出结果。该框架虽简单,但涵盖了RPC核心流程:代理、网络传输、序列化与反射。

实现一个简单的 RPC(远程过程调用)框架,核心目标是让客户端像调用本地方法一样调用远程服务。我们可以通过 Java 的接口代理、反射、Socket 通信和序列化机制来手写一个轻量级的 RPC 框架。
一个最简 RPC 框架需要以下几个部分:
首先定义一个服务接口,客户端和服务端都要依赖它。
public interface HelloService {
String sayHello(String name);
}
再定义一个用于封装 RPC 请求的消息体:
立即学习“Java免费学习笔记(深入)”;
import java.io.Serializable;
public class RpcRequest implements Serializable {
private static final long serialVersionUID = 1L;
private String methodName;
private Class<?>[] paramTypes;
private Object[] args;
// 构造函数、getter、setter 省略
public RpcRequest() {}
public RpcRequest(String methodName, Class<?>[] paramTypes, Object[] args) {
this.methodName = methodName;
this.paramTypes = paramTypes;
this.args = args;
}
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[] getArgs() { return args; }
public void setArgs(Object[] args) { this.args = args; }
}
响应消息类:
import java.io.Serializable;
public class RpcResponse implements Serializable {
private static final long serialVersionUID = 1L;
private Object result;
public RpcResponse() {}
public RpcResponse(Object result) { this.result = result; }
public Object getResult() { return result; }
public void setResult(Object result) { this.result = result; }
}
服务端启动一个 ServerSocket,监听客户端请求,反序列化请求,通过反射调用本地方法,再把结果序列化返回。
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.lang.reflect.Method;
public class RpcServer {
private int port;
private Object service;
public RpcServer(int port, Object service) {
this.port = port;
this.service = service;
}
public void start() throws IOException {
ServerSocket serverSocket = new ServerSocket(port);
System.out.println("RPC 服务器启动,监听端口:" + port);
while (true) {
Socket socket = serverSocket.accept();
handleRequest(socket);
}
}
private void handleRequest(Socket socket) {
try (
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream())
) {
RpcRequest request = (RpcRequest) ois.readObject();
Method method = service.getClass().getMethod(
request.getMethodName(),
request.getParamTypes()
);
Object result = method.invoke(service, request.getArgs());
oos.writeObject(new RpcResponse(result));
oos.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
try { socket.close(); } catch (IOException e) { }
}
}
}
客户端通过动态代理生成接口的实现,所有方法调用都会被拦截,转为远程调用。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.io.*;
import java.net.Socket;
public class RpcClientProxy {
public <T> T getProxy(final Class<T> interfaceClass, final String host, final int port) {
return (T) Proxy.newProxyInstance(
interfaceClass.getClassLoader(),
new Class[]{interfaceClass},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Socket socket = new Socket(host, port);
try (
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream())
) {
RpcRequest request = new RpcRequest(method.getName(), method.getParameterTypes(), args);
oos.writeObject(request);
oos.flush();
RpcResponse response = (RpcResponse) ois.readObject();
return response.getResult();
} finally {
socket.close();
}
}
}
);
}
}
public class HelloServiceImpl implements HelloService {
@Override
public String sayHello(String name) {
return "Hello, " + name + "!";
}
}
启动服务端:
public class ServerApp {
public static void main(String[] args) throws IOException {
HelloService helloService = new HelloServiceImpl();
RpcServer server = new RpcServer(8888, helloService);
server.start();
}
}
启动客户端:
public class ClientApp {
public static void main(String[] args) {
RpcClientProxy clientProxy = new RpcClientProxy();
HelloService service = clientProxy.getProxy(HelloService.class, "localhost", 8888);
String result = service.sayHello("World");
System.out.println(result); // 输出: Hello, World!
}
}
以上就是java怎么实现一个简单的RPC框架 手写轻量级RPC通信机制的详细内容,更多请关注php中文网其它相关文章!
java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号