简易版RPC
rpc-easy
代理工厂,负责根据消费者的需要,向服务提供者的指定地址发送请求,将接收到的请求送给消费者。
example-common(公共模块):
User.java 消费者和提供者都需要的实体类
UserService.java 接口
example-consumer(服务消费者):
引入公共模块
example-provider(服务提供者):
引入公共模块
导入代理,通过代理工厂,获取到UserService接口的实现类UserService.class
//导入静态代理
UserService userService = new UserServiceProxyO);
//导入动态代理
UserService userService =ServiceProxyFactory.getProxy(UserService.class);
进入代理,代理使用JDK动态代理来实现,帮我们创建一个代理对象
//进入代理
public static <T> T getProxy(Class<T> serviceclass){
return (T) Proxy.newProxyInstonce(
serviceClass.getClassLoaderO,
new Class[](serviceclass},
new ServiceProxy());
}
此时通过代理工厂获取到UserService接口的实现类UserService.class,并不等于服务提供者的UserService实现类。这个代理工厂获取到的实现类的作用,是向指定的地址发请求。
//代理的逻辑
@override
public Object invoke(Object proxy, Method method,Object[] args) throws Throwable {
//指定序列化器
Serializer serializer = new JdkSerializerO;
//构造请求
RpcRequest rpcRequest = RpcRequest.builder()
.serviceName(method.getDeclaringClass().getName(O)
.methodName(method.getName(O))
-parameterTypes(method.getParameterTypes())
.args(args)
.build();
try
∥序列化
byte[] bodyBytes = serializer.serialize(rpcRequest);
//向服务提供者发送请求
//todo注意,这里地址被硬编码了(需要使用注册中心和服务发现机制解决)
try (HttpResponse httpResponse= HttpRequest.post(url:"http://Localhost:8888".body(bodyBytes)
.executeO) {
byte[] result = httpResponse.bpdyBytes(;
// 反序列化
RpcResponserpcResponse=serializer.deserialize(result,RpcResponse.class);
return rpcResponse.getData();
}catch (IOException e){
e.printstackTraceO;
服务消费者->调用公共模块->公共模块调入代理工厂->代理工厂向指定地址发送请求->调用服务提供者->得到响应
总结:
RPC框架通过代理对象,帮消费者简化调用的代码;通过请求处理器,web服务器,帮助服务提供者简化接受请求,处理请求的过程。
扩展版RPC
配置文件:全局配置加载
不用把配置信息在代码里写死,让服务提供者和消费者通过编写配置文件,指定RPC框架的行为,
rpc.name=yurpc
rpc.version=2.0
rpc.mock=false
rpc.serializer=jdk
rpc.serverPort=8081
rpc.serverHost=localhost
接口Mock:增强消费者能力
什么是Mock?
RPC框架的核心功能是调用其他远程服务。但是在实际开发和测试过程中,有时可能无法直接访问真实的远程服务,或者访问真实的远程服务可能会产生不可控的影响,例如网络延迟、服务不稳定等。在这种情况下,就需要使用mock服务返回一些假的数据、模拟的数据来模拟远程服务的行为,以便进行接口的测试、开发和调试。
mock是指模拟对象,通常用于测试代码中,特别是在单元测试中,便于我们跑通业务流程。
序列化器与SPI机制
什么是 SPI?
SPI(Service Provider Interface)服务提供接口是Java的机制,主要用于实现模块化开发和插件化扩展。
SPI机制允许服务提供者通过特定的配置文件将自己的实现注册到系统中,然后系统通过反射机制动态加载这些实现,而不需要修改原始框架的代码,从而实现了系统的解耦、提高了可扩展性。
一个典型的SPI应用场景是JDBC(Java数据库连接库),不同的数据库驱动程序开发者可以使用JDBC库,然后定制自己的数据库驱动程序。
此外,我们使用的主流Java开发框架中,几乎都使用到了SPI机制,比如Servlet容器、日志框架、ORM框架、Spring框架。
spi扩展可以不改变rpc框架代码