极简 RPC 骨架实现¶
一、RPC 要解决什么¶
让本地调用远程方法像调用本地方法一样。核心步骤:
- 代理:客户端生成接口代理对象。
- 序列化:方法名、参数序列化成字节。
- 网络传输:把字节发给服务端。
- 反序列化 + 反射调用:服务端根据字节调用真实方法。
- 返回结果序列化发回客户端。
二、最小实现¶
1. 公共接口¶
2. 服务端实现¶
public class HelloServiceImpl implements HelloService {
public String sayHello(String name) {
return "Hello, " + name;
}
}
3. 服务端骨架¶
用 JDK HttpServer 监听端口,反射调用:
public class RpcServer {
public void start(int port, Object service) throws Exception {
HttpServer server = HttpServer.create(new InetSocketAddress(port), 0);
server.createContext("/rpc", exchange -> {
byte[] req = exchange.getRequestBody().readAllBytes();
// 反序列化:得到 className, methodName, paramTypes, args
RpcRequest rpcReq = JSON.parseObject(req, RpcRequest.class);
Method m = service.getClass()
.getMethod(rpcReq.getMethodName(), rpcReq.getParamTypes());
Object result = m.invoke(service, rpcReq.getArgs());
byte[] resp = JSON.toJSONBytes(result);
exchange.sendResponseHeaders(200, resp.length);
try (OutputStream os = exchange.getResponseBody()) {
os.write(resp);
}
});
server.start();
}
}
4. 客户端代理¶
public class RpcClient {
@SuppressWarnings("unchecked")
public static <T> T proxy(Class<T> interfaceClass, String host, int port) {
return (T) Proxy.newProxyInstance(
interfaceClass.getClassLoader(),
new Class<?>[]{interfaceClass},
(proxy, method, args) -> {
RpcRequest req = new RpcRequest(
interfaceClass.getName(),
method.getName(),
method.getParameterTypes(),
args
);
// HTTP 发请求
HttpURLConnection conn = (HttpURLConnection)
new URL("http://" + host + ":" + port + "/rpc").openConnection();
conn.setRequestMethod("POST");
conn.getOutputStream().write(JSON.toJSONBytes(req));
// 读响应
byte[] resp = conn.getInputStream().readAllBytes();
return JSON.parseObject(resp, method.getReturnType());
}
);
}
}
5. 使用¶
// 服务端
new RpcServer().start(8080, new HelloServiceImpl());
// 客户端
HelloService service = RpcClient.proxy(HelloService.class, "127.0.0.1", 8080);
System.out.println(service.sayHello("World"));
三、生产级 RPC 要加什么¶
| 能力 | 作用 |
|---|---|
| 服务注册发现 | 不用写死 IP |
| 负载均衡 | 多提供者选一个 |
| 序列化优化 | Protobuf / Kryo |
| 网络框架 | Netty,不用 HTTP |
| 超时重试 | 容错 |
| 监控埋点 | 耗时、错误率 |
| 压缩 | gzip |
面试加分
- 手写 RPC 核心考:动态代理、序列化、网络通信、反射调用。
- 升级版:用 Netty + Hessian2 + Zookeeper/Nacos 注册中心。