一、基础的概念
- 负载均衡:将大量用户请求分摊到不同的服务器上处理,以提高系统整体的并发处理能力以及可靠性。
- 容错机制:(如果服务器接口调用失败,该如何处理)为保证分布式系统的高可用,会给服务器的调用机制增加容错机制。如失败重试,降级调用其他接口等。
开发一个简易的RPC框架

项目初始化
-
common:公共模块(会同时被消费者和提供者引用)
基础的数据模型和服务相关的接口。
-
provider:服务提供者模块(需要暴露接口,等待消费者调用)
-
consumer:消费者模块(需要引入rpc和common依赖)
-
easy-rpc:简易rpc框架
①请求处理器
java
import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;
import java.io.IOException;
import java.lang.reflect.Method;
/**
* HTTP 请求处理器处理请求
*/
public class HttpServerHandler implements Handler<HttpServerRequest> {
@Override
public void handle(HttpServerRequest request) {
// 指定序列化器
final Serializer serializer = new JdkSerializer();
// 记录日志
System.out.println("Received request: " + request.method() + " " + request.uri());
// 异步处理 HTTP 请求
request.bodyHandler(body -> {
byte[] bytes = body.getBytes();
RpcRequest rpcRequest = null;
try {
// 对请求反序列化,消费者发送的数据是byte字节数组需要转为Java对象
rpcRequest = serializer.deserialize(bytes, RpcRequest.class);
} catch (Exception e) {
e.printStackTrace();
}
// 构造响应结果对象
RpcResponse rpcResponse = new RpcResponse();
// 如果请求为 null,直接返回
if (rpcRequest == null) {
rpcResponse.setMessage("rpcRequest is null");
doResponse(request, rpcResponse, serializer);
return;
}
try {
// 获取要调用的服务实现类,通过反射调用
Class<?> implClass = LocalRegistry.get(rpcRequest.getServiceName());// 在注册中心获取服务名称
Method method = implClass.getMethod(rpcRequest.getMethodName(), rpcRequest.getParameterTypes());// 反射获取方法名称
Object result = method.invoke(implClass.newInstance(), rpcRequest.getArgs());// 通过反射调用方法
// 封装返回结果
rpcResponse.setData(result);
rpcResponse.setDataType(method.getReturnType());
rpcResponse.setMessage("ok");
} catch (Exception e) {
e.printStackTrace();
rpcResponse.setMessage(e.getMessage());
rpcResponse.setException(e);
}
// 响应
doResponse(request, rpcResponse, serializer);
});
}
/**
* 响应
*
* @param request
* @param rpcResponse
* @param serializer
*/
void doResponse(HttpServerRequest request, RpcResponse rpcResponse, Serializer serializer) {
HttpServerResponse httpServerResponse = request.response()
.putHeader("content-type", "application/json");
try {
// 序列化
byte[] serialized = serializer.serialize(rpcResponse);
httpServerResponse.end(Buffer.buffer(serialized));
} catch (IOException e) {
e.printStackTrace();
httpServerResponse.end(Buffer.buffer());
}
}
}
②请求类&响应类
java
import java.io.Serializable;
/**
* RPC 请求
*/
public class RpcRequest implements Serializable {
/**
* 服务名称
*/
private String serviceName;
/**
* 方法名称
*/
private String methodName;
/**
* 参数类型列表
*/
private Class<?>[] parameterTypes;
/**
* 参数列表
*/
private Object[] args;
public String getServiceName() {
return serviceName;
}
public RpcRequest(String serviceName, String methodName, Class<?>[] parameterTypes, Object[] args) {
this.serviceName = serviceName;
this.methodName = methodName;
this.parameterTypes = parameterTypes;
this.args = args;
}
public void setServiceName(String serviceName) {
this.serviceName = serviceName;
}
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
public Class<?>[] getParameterTypes() {
return parameterTypes;
}
public void setParameterTypes(Class<?>[] parameterTypes) {
this.parameterTypes = parameterTypes;
}
public Object[] getArgs() {
return args;
}
public void setArgs(Object[] args) {
this.args = args;
}
}
响应类
java
import java.io.Serializable;
/**
* RPC 响应
*/
public class RpcResponse implements Serializable {
/**
* 响应数据
*/
private Object data;
/**
* 响应数据类型(预留)
*/
private Class<?> dataType;
/**
* 响应信息
*/
private String message;
/**
* 异常信息
*/
private Exception exception;
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public Class<?> getDataType() {
return dataType;
}
public void setDataType(Class<?> dataType) {
this.dataType = dataType;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Exception getException() {
return exception;
}
public void setException(Exception exception) {
this.exception = exception;
}
}
③服务注册类
java
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import static java.util.Objects.nonNull;
/**
* 本地注册器(理解为注册中心的作用)
*/
public class LocalRegistry {
/**
* 注册中心
*/
private static final Map<String, Class<?>> registryMap = new ConcurrentHashMap<>();
/**
* 注册
*/
public static void registry(String serviceName, Class<?> clazz) {
registryMap.put(serviceName, clazz);
}
/**
* 删除
*/
public static void remove(String serviceName, Class<?> clazz) {
registryMap.remove(serviceName);
}
/**
* 获取
*/
public static Class<?> get(String serviceName) {
Class<?> aClass = registryMap.get(serviceName);
if (nonNull(aClass)) {
return aClass;
}
throw new RuntimeException("当前请求接口不存在:" + serviceName);
}
}
④消费者的请求代理
java
/**
* 静态代理 调用服务提供者
*/
public class UserServiceProxy implements UserService {
@Override
public User getUser() {
RpcRequest rpcRequest = new RpcRequest(UserService.class.getName(), "getUser", new Class[]{}, new Object[]{});
Serializer serializer = new JdkSerializer();
try {
byte[] bytes = serializer.serialize(rpcRequest);
HttpResponse response = HttpRequest.post("http://localhost:8099/").body(bytes).execute();
RpcResponse rpcResponse = serializer.deserialize(response.bodyBytes(), RpcResponse.class);
return (User) rpcResponse.getData();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}