当前位置: 首页 > news >正文

手写RPC框架-V1版本

配合源代码使用体验更佳

  • Version 1.0
    • 一、Provider模块
      • 1.ProviderExample
      • 2.UserServiceImpl
      • pom.xml
    • 二、Consumer模块
      • 1.ConsumerExample
      • 3.UserServiceProxy(静态代理)
      • pom.xml
    • 三、RPC模块
    • Proxy包
      • 1.ServiceProxy
      • 2.ServiceProxyFactory
    • Registry包
      • LocalRegisty
    • Serializer包
      • 1.JDKSerializer
      • 2.Serializer接口
    • Server包(提供Web服务)
      • 1.HttpServer
      • 2.HttpServerHandler
      • 3.VertxHttpServer
    • pom.xml
    • 四、Common模块
      • 1.RpcRequest
      • 2.RpcResponse
      • 3.User
      • pom.xml
  • V1源代码
  • 常见报错以及解决方法
    • 1.NullPointException
    • 2.EOFException
    • 3.NotSerializabel
    • 4.IDEA调式传参为java.lang.Object
    • 5.编码过程中的一些问题

Version 1.0

一、Provider模块

1.ProviderExample

Main:
1.当我们启动ProviderExample main的时候,首先我们会注册我们的服务,传入以下参数:(Service.class.getName(),ServiceImpl.class)
className和Impl.class 将被传给注册中心LocalRegistry 。 注册中心会将 类路径 以及 类实现class 传入到 私有的不可变map中,这个map由ConcurrentHashMap实现了线程安全。

2.通过rpc提供的web服务接口new webserver,并且调用doStart(int port)方法(硬编码:8080)。

rpc提供的 VertixHttpServer 实现了 HttpServer接口 有doStart方法。这个方法首先会初始化vertx 然后初始化HttpServer

io.vertx.core.http.HttpServer server = vertx.createHttpServer();

3.然后启动server.requestHandler(new Handler()) 去处理请求并且持续监听端口。

2.UserServiceImpl

远程方法接口实例。

pom.xml

引入了 rpc common lombok hutool-all 四个依赖

二、Consumer模块

1.ConsumerExample

main方法获取目标服务

UserService userService = ServiceProxyFactory.getProxy(UserService.class)

消费者包装了一个:fqxiny用户,满足某个方法的变量格式,然后调用远程方法 getUser
打印用户信息并且返回用户信息。远程方法服务器能够接收到这个变量,消费者能够远程调用方法,获得返回值。
返回值传给消费者,方式是在远程调用而不是被拿过来了。远程方法也能够接收参数。

3.UserServiceProxy(静态代理)

rpc消费者代理:指定构造器,初始化请求,请求序列化,发送请求到目标地址(硬编码)

另一边:(目标地址接收请求,获取请求参数,查找服务,使用服务,获得结果,初始化响应,响应序列化,响应消费者)

然后消费者代理proxy,接收响应,并反序列化获得方法调用结果。

pom.xml

引入了 rpc common hutool-all lombok 依赖

三、RPC模块

Proxy包

1.ServiceProxy

动态服务代理实例,实现了InvocationHandler接口,重写了invoke方法。

invoke方法接收 proxy,method,args 三个形参。

方法区跟静态代理是一样的,但是这里的目标地址不符合动态代理思想,应该修改为一个全局配置,这也是第二版的内容。

指定序列化器-请求初始化(封装消息)-序列化-发送-响应-接收响应-反序列化-getData

2.ServiceProxyFactory

public class ServiceProxyFactory {

    public static <T> T getProxy(Class<T> serviceClass) {
        return (T) Proxy.newProxyInstance(
                serviceClass.getClassLoader(),
                new Class[]{serviceClass},
                new ServiceProxy());
    }
}

这是一个工厂模式

Registry包

LocalRegisty

上文提及,是一个注册中心,其中有注册服务和获取服务两个方法,服务全限定名 和 实现类class 以 entry的形式存储在一个private final static ConcurrentHashMap中

Serializer包

1.JDKSerializer

实现了Serializer接口,通过Java中的转换流实现序列化和反序列化

2.Serializer接口

序列化接口,提供序列化和反序列化方法

Server包(提供Web服务)

1.HttpServer

server方法 开启端口

2.HttpServerHandler

核心方法-处理请求

初始化序列化器 ,记录日志,异步处理HTTP请求,构造响应结果对象,判断请求值,通过请求参数获得服务class,通过反射调用服务,封装返回结果。

3.VertxHttpServer

实现server 并且使用了vertix开启端口和监听请求

pom.xml

引入了 hutool-all vert.x lombok

四、Common模块

1.RpcRequest

请求格式

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class RpcRequest implements Serializable {

    /*服务名称*/
    private String serviceName;

    /*方法名称*/
    private String methodName;

    /*参数类型*/
    private Class<?>[] parameterTypes;

    /*参数值*/
    private Object[] args;

}

2.RpcResponse

响应格式

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class RpcResponse implements Serializable {
    /*响应数据*/
    private Object data;
    /*响应状态*/
    private Class<?> dataType;
    /*响应信息*/
    private String message;
    /*异常信息*/
    private Exception exception;
}

3.User

DTO

pom.xml

引入了RPC和Lombok依赖

V1源代码

https://github.com/fqxiny/-0-1-RPC-

常见报错以及解决方法

1.NullPointException

经常出现在请求响应 method.invoke() 出的classImpl为null的情况。
说明你的类路径或者是class 注册错了,可以在map.get方法中尝试打印

2.EOFException

可以增加流的关闭方法

3.NotSerializabel

请求 或者 响应 没有实现序列化

4.IDEA调式传参为java.lang.Object

转为run 看看报错,或者退出IDEA多试几次

5.编码过程中的一些问题

  • Maven依赖配置错误
  • 导包错误
  • 编码错误

相关文章:

  • 无人机与AI!
  • MyBatis-Plus注解配置:@TableName、@TableId、@TableField
  • 浙江大学《程序设计入门-c语言》第一周笔记
  • Java进阶——Stream流以及常用方法详解
  • 蓝桥杯 - 简单 - 俄罗斯方块
  • IDEAPyCharm安装ProxyAI(CodeGPT)插件连接DeepSeek-R1教程
  • 学术小助手智能体
  • rust学习~tokio的io
  • 网络安全技术概述
  • 【安卓】BroadcastReceiver 动态声明为 RECEIVER_NOT_EXPORTED 后无法接收任何 Intent 的问题
  • 结构化方法SASD
  • openGauss数据库使用
  • 谈谈 Node.js 中的文件系统(fs)模块,如何进行文件读写操作?
  • CSS—背景属性与盒子模型(border、padding、margin)
  • 越南SD-WAN跨境组网专线助力制造业访问国内 OA、ERP系统难题
  • Go基于协程池的延迟任务调度器
  • 《Kafka 理解: Broker、Topic 和 Partition》
  • 【leetcode】二分查找专题
  • 打造爆款秘籍:利用ARA数据优化亚马逊广告策略
  • STM32呼吸灯实验手册(TIM定时器)
  • 做网站 需求怎么写/近期新闻事件
  • 网站都有什么功能/中国职业培训在线官网
  • 微信第三方网站怎么做/本地建站软件有哪些
  • 网站建设免费空间注册导航/抖音搜索排名优化
  • 濮阳新闻综合频道直播/关键词排名优化营销推广
  • 网站设计指南/模板建站常规流程