# netty-rpc **Repository Path**: whiteandy/netty-rpc ## Basic Information - **Project Name**: netty-rpc - **Description**: 一个自研的基于netty的rpc调用系统demo,netty IO通信模拟,基于netty的raft算法实现。仅供学习和参考。由于时间有限,很多地方有待优化。 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 3 - **Forks**: 3 - **Created**: 2021-03-11 - **Last Updated**: 2022-05-14 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 一.基于netty的rpc ### **1.简介** 本系统是一个自研的基于netty的rpc调用系统demo。仅供学习和参考。由于时间有限,很多地方有待优化。 支持服务注册和发现。 ### **2.使用方式** 1.启动注册中心 运行 RegisterServerContextImpl 2.启动服务提供者 运行 Provider,通过修改端口 可以 启动多个 3.启动服务调用者 运行 Consumer ### **3.系统架构** ![输入图片说明](https://images.gitee.com/uploads/images/2021/0401/094701_a1a7e609_5311479.png "自研rpc.png") ## 4.技术说明 1.基于netty实现 2.传输报文,固定头部大小。报文体的大小通过 int类型表示。限定了报文的大小。 3.采用Kryo进行序列化。未实现 字节的 压缩算法 4.使用jdk的动态代理,注册的服务依赖接口 5.租期续约采用滑动窗口的方式进行统计 ======================================================================================= ## 二.netty模拟 使用java的 nio 模拟了 一个简单的netty。 采用主从的线程结构,支持报文的拆包。 主线程获取连接,从线程处理I/O操作 ![输入图片说明](https://images.gitee.com/uploads/images/2021/0401/094727_4d13ee2f_5311479.png "netty模拟-支持拆包.png") ## 三.基于netty的raft选举算法实现 ### 1.状态转换图 ![输入图片说明](https://images.gitee.com/uploads/images/2021/0401/094747_ed28638a_5311479.png "raft-状态转换图.png") ### 2.系统介绍 1.系统启动的时候,默认为follower状态。启动心跳监听(**心跳周期为一定范围的随机值**) 2.收到心跳信息,自己为follower,等待接收消息;超时未收到心跳,修改状态为候选者,选举自己为leader,推荐其他server选举自己。发送的报文中是当前任期+1(这时自己的任期并没有真正增一) 3.1自己被选为leader。状态变为leader。停止心跳监听。给其他server发送心跳。启动消息同步提交任务。且leader维护三个server列表: 一个是全量的server列表:发送心跳使用 一个是同步(消息logindex同步)的server列表:发送消息使用 一个是非同步(消息logindex非同步)的server列表:同步消息使用,一个列表一个线程进行同步。 3.2自己没有被选为leader,状态变更为follower,修改心跳监听周期(**一定范围的随机值**),等待接受心跳信息。没有心跳到步骤2 有两个地方可以触发数据同步: 发送写消息,写失败且logindex小; 心跳消息的返回信息中携带自己的logindex,leader会检查当前server的logindex与自己的logindex,如果小于自己,则当前server进入同步列表,进行消息同步 **任期的管理**: 1.选举的时候,将当前任期加1发送消息,选举成功,任期增1. 2.心跳消息中,leader任期大于自己,更新自己的任期。 3.推荐其他server选举自己时,返回不投给自己的消息投票选举中,检查人气是否大于自己,是的话更新自己的任期 4.选举时,如果发现任期大于自己,更新自己的任期。 5.leader发送心跳,被拒绝时,检查任期是否大于自己。是的话更新自己的任期。降级为follower **一些问题** 1.消息体共用,导致消息体里面会有好多冗余属性 2.消息的密等性:使用了报文中的messageId 3,没有写持久化方法 4.想用lombok,引入依赖后,系统没有报错,但是无法编译。就生成了get set方法 5.查询的时候,没有考虑删除,当前消息是已提交状态(可能已经删除-暂时不考虑),直接返回。未提交状态则把leader返回给了客户端。由客户端自己访问leader查询。 ### 3.系统使用 1.因为是在一台机上开发。所以系统默认启用的端口是9090,9091,9092 2.修改ChooserContext的port属性,并启动三个实例9090,9091,9092 3.启动main方法,会启用多个线程去写数据。 4.可以打开Partners中heartBeat方法中带有 “ 模拟心跳丢失,会切换leader” 的注释代码,模拟心跳丢失,触发重新选主。也可以直接关闭主机,触发重新选主。 ### 4.优化 查询的时候,follower可以维护一个状态 是否是同步副本。 可以根据消息类型维护。若消息类型为5,则为同步消息,说明当前server不是同步server,需要到leader上去查询。如果为同步副本,可以直接从本机查询。