-
Notifications
You must be signed in to change notification settings - Fork 0
0xnofoot/nRPC
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
项目介绍: nRPC是一款轻量级的RPC框架,基于Zookeeper,Redis,Netty,Spring等技术实现,能够提供基本的远程过程调用服务。 该项目分为Common(通用组件代码),Server(服务提供端),Client(服务调用端)三个模块,通过Maven管理工程,支持注解开发, 基于接口实现远程调用,要求服务端和调用端共用一套接口和实体类库以保证正确调用服务和结果获取。 用户只需要导入对应的模块坐标,正确使用注解即可以实现无感知调用远端服务获取方法调用的结果。 负责功能: 1.注册中心 nRPC目前提供了两种注册中心的实现,分别是Zookeeper和Redis,支持通过配置文件进行配置。 1.1.服务注册 nRPC建议使用注解注册服务,在Server模块中依赖Spring自动扫描Bean,通过后处理器实现服务注册。 服务名称格式由服务类实现接口名称,所属组名称以及版本号组成。 Zookeeper通过注册服务节点及服务地址子节点实现服务注册;Redis通过Set集合实现服务注册。 1.2.服务发现 在Client模块实现服务发现功能,支持随机和一致性哈希两种负载均衡策略(默认使用一致性哈希),实现服务地址的获取。 Zookeeper实现下,提供本地地址缓存功能,依靠监听服务节点做到及时更新本地缓存地址; Redis实现下,提供调用结果缓存功能,由服务名称,参数类型名称,参数三部分组合并经过哈希运算作为Key将调用结果缓存至Redis。 2.网络消息传输 nRPC的底层网络通信依赖Netty实现,通过自定义协议完成高效的服务调用。 2.1.协议设计 nRPC的网络传输协议由消息头和消息体组成, 通过 RpcMessage 实体类封装,消息头共16个字节,其中包括: 魔数,协议版本,消息总长度,消息类型,序列化类型,数据压缩类型,消息编号 消息体由 RpcRequest 或 RpcResponse 实体类封装, RpcRequest 来自Client端,其中主要包含请求服务的元数据信息,如接口名称,服务标识,请求方法等 RpcResponse 来自Server端,其中主要包含对应的请求ID,服务调用的结果等。 2.2.编解码器 nRPC中涉及网络通信的实体类只有上述提到了三个类,因此Server模块和Client模块的编解码逻辑复用了同一段代码 这种设计简化了开发,提高了代码复用性,但存在代码耦合高的问题。 nRPC实现了Protostuff,Hessian,Kyro三种序列化机制,默认使用Protostuff,统一使用Gzip进行数据压缩。 对于编码器,首先依靠 RpcMessage 对象写入除了消息总长度外的所有消息头信息至缓冲区, 然后将消息体对象进行序列化并压缩再写入,最后写入消息总长度,然后消息出站,编码结束。 对于解码器,首先校验魔数和协议版本,校验通过后读取剩余消息头信息, 并通过信息正确读取消息体进行解压缩和反序列化,构建 RpcMessage 对象,消息入站,解码结束。 2.3.心跳机制 为了维持网络连接,nRPC的网络通信消息包中存在 PING 和 PONG 两个心跳检测包, Client端会每分钟向Server端发送PING包,Server端收到后会回复PONG包,以此维护网络连接, 如果Server端五分钟没有收到PING包,那么就会关闭该连接。 3.代理调用 nRPC采用代理模式实现远程调用,Client端启动时会依赖Spring扫描需要注入代理的字段。 在后处理器中为每个字段构建代理类,并生成代理对象注入该字段。 当这些字段执行方法时就会代理到对应的invoke()方法中,并执行服务发现,消息构建,发送调用请求等逻辑。 4.结果获取优化 nRPC的设计框架下只有当消息入站并解码处理后才能获取到调用结果,由于Netty是异步非阻塞事件驱动的, 所以nRPC采用 CompletableFuture 实现等待/通知机制, 发送调用请求前会构造一个CompletableFuture 对象并存入Map集合,调用请求发送后返回该CompletableFuture 对象 主线程执行该CompletableFuture 的join()方法阻塞在此处等待结果到达, 接收到调用结果后根据请求ID从Map集合中获取对应的CompletableFuture 对象并传入结果,主线程就会结束阻塞获取到结果。
About
No description, website, or topics provided.
Resources
Stars
Watchers
Forks
Releases
No releases published
Packages 0
No packages published