Sofa-jraft的Rpc调用服务端分析

news2024/11/27 14:28:48
  1. 在sofa-jraft中,关于RPC的服务端是RpcServer

在RpcServer中的init方法中:

初始化了连接事件监听器,这个里面就是一个map,然后可以添加事件监听的处理器,初始化userProcessors, codec 是一个编码和解码器的工厂,可以获取编码器和解码器,然后他调用了父类的构造器super(port);

父类AbstractRemotingServer则是初始化了ip,port, options容器,包含BitSet的globalSwitch 全局开关,配置容器,configContainer,实现了接口RemotingServer : 这个接口主要是可以注册处理器

到此,已经完成了初始化,就是初始化一些map,开关,编码解码器,等,而AbstractRemotingServer继承了AbstractLifeCycle:我们来看下这个lifeCycle:

就是通过Atomic变量来控制启动和关闭

那么来看下start()方法,这个方法是RemotingServer的,实现在AbstractRemotingServer中,调用了startup方法(覆盖LifeCycle的方法),所以这两个方法其实是一样的,然后是doInit方法,这个是抽象方法,由RpcServer实现:

首先是根据是否管理Connection参数来初始化连接管理器,无论是否管理连接,都会初始化Eventhandler ,这里面实现了一些连接事件,大多数事件是没有自定义处理,都是打印日志

initRpcRemoting() 这个是初始化RpcRemoting也就是远程调用,这个可以后面说

这里就是初始化Netty的bootstrap,包括设置tcp参数,接收队列发送队列大小等,并设置高水位和低水位

这里是设置触发模式,水平触发还是边缘触发,如果是epoll,则设置为水平触发,否则设置为边缘触发

这里科普一下水平触发和边缘触发:

首先我们的网络模型select / poll, epoll 会有一个读取的调用,他们的方法都不一样,比如epoll的epoll_read ,如果是水平触发,那么如果是有一大串数据过来之后,读取一次没有读取完,那么就又会有一次读就绪事件,如果每次发送的数据量比较大,那么这种读事件就会有很多,会浪费很多的系统资源(文件描述符,事件触发也会有消耗)

如果是边缘触发,那么数据没读完,不会有事件过来,也就是调用epoll_read不会有返回,这样就需要自己在一次触发的时候吧缓冲空间的数据读完。

那么水平触发的场景可以是短报文场景,边缘触发可以是大报文场景

水平触发优、缺点及应用场景:
优点:当进行socket通信的时候,保证了数据的完整输出,进行IO操作的时候,如果还有数据,就会一直的通知你。
缺点:由于只要还有数据,内核就会不停的从内核空间转到用户空间,所有占用了大量内核资源,试想一下当有大量数据到来的时候,每次读取一个字节,这样就会不停的进行切换。内核资源的浪费严重。效率来讲也是很低的。
LT要避免写的死循环问题,写缓冲区满的概率很低,只要缓冲区没满(空闲)就会不断发信号,所以写完数据后一定要记得取消写事件。
边沿触发优、缺点及应用场景:
优点:每次内核只会通知一次,大大减少了内核资源的浪费,提高效率。
缺点:不能保证数据的完整。不能及时的取出所有的数据。
应用场景:处理大数据。使用non-block模式的socket。
ET要避免"short read"的问题,比如用户收到100个字节,触发了一次边沿警告,读了50个字节,剩下50个字节没读。但是没有警告。

接下来是设置时间处理器,ServerIdleHandler是当服务端发生了Idle事件的时候关闭链接,RpcHandler初始化的时候将userProcessor传入了参数

收到消息的以后会进行消息分发,我们后面单独看ProtocolCode及消息的分发处理,而在最后如果有新的连接,怎会加入到connectionmanager中

回到Abstract的startup,最后则是进行启动,而这个启动doStart()是在RpcServer中,绑定端口,启动用户处理器等

接下来先分析编码器和解码器:

编码器:

首先会从channel中获取协议版本,然后通过协议管理器来获取编码器,

两个版本的编码器,在字节流的首个字节都写入了PROTOCOL_CODE,以及content和header的长度

解码器:

解码器的流程是,先解析出协议的版本,将协议code写入channel的attribute,然后重置读指针,获取版本对应的解码器进行解码,而解码的流程也比较简单,逐个获取各个数据,根据长度将数据填入对象中

再一个就是用户处理器:

收到消息的事件处理器是RpcHandler,通过协议获取到RpcCommandHandler,在handle中,通过

来获取processor,在解码器中已经解析出了commandType,

而processorManager是RpcCommandHandler初始化的时候构造的,并注入了几个默认的processor

而在RPC_REQUESTprocessor中,

首先通过request的类型获取用户processor中的处理器来处理

而后就是增加一些选择器以及线程池选择,这里看下userprocessor到底有哪些

其实这里的userprocessor中有很多都是内部类,每一种消息类型都有对应的处理器,举个例子

选举投票有预选举,预选举跟选举的区别是不增长任期,并且设置preVote为true,避免网络发生隔离后重新加入集群,增加任期选举时因为任期无线增大的情况

这里封装的Request是RequestVoteRequest,rpcService.preVote 会在消息发送后执行done的Run方法

在构造RaftGroupService的时候,也可以是在通过RaftRpcServerFactory来创建RpcServer的时候:

会提前注入很多相关的处理器

而在回调的时候会调用processor的handleRequest方法,我们来看RequestVoteRequestProcessor:

handleRequest 在父类的父类RpcRequestProcessor中,调用子类的processRequest,接着再调用子类RequestVoteRequestProcessor的processRequest0方法,这里面则是具体的处理逻辑方法

我们的消息格式都是RpcRequestCommand,通过这个来进行编码和解码,而里面的requestClass,是在构造Command的时候注入的:

这是客户端发送消息时的最后转换处理,

解码后根据requestclass对应processor的interest

这样逻辑就能对应上了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/364557.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VPS使用ProxySU搭建节点服务器

本文所有教程及源码、软件仅为技术研究。不涉及计算机信息系统功能的删除、修改、增加、干扰,更不会影响计算机信息系统的正常运行。不得将代码用于非法用途,如侵立删! VPS使用ProxySU搭建节点服务器 环境 contos8win10 64位ProxySU 4.1.7 服…

02-mysql高级-

文章目录mysql高级1,约束1.1 概念1.2 分类1.3 非空约束1.4 唯一约束1.5 主键约束1.6 默认约束1.7 约束练习1.8 外键约束1.8.1 概述1.8.2 语法1.8.3 练习2,数据库设计2.1 数据库设计简介2.2 表关系(一对多)mysql高级 今日目标 掌握约束的使用 掌握表关系…

自动化测试——css元素定位

文章目录一、css定位场景二、css相对定位的优点三、css的调试方法1、表达式中含有字符串:表达式中的引号一定和外面字符串的引号相反四、css基础语法1、标签定位2、class定位特别注意:当class类型的属性值包含多个分割值,$(.s_tab s_tab_1z9n…

快捷式~node.js环境搭建

1、安装包官网下载:Node.js (nodejs.org) 2、安装完成后修改环境变量 在上面已经完成了 node.js 的安装,即使不进行此步骤的环境变量配置也不影响node.js的使用 但是,若不进行环境变量配置,那么在使用命令安装 node.js全局模块 …

Linux服务:Nginx服务配置及相关模块

目录 一、Nginx配置文件 1、主配置文件解析 2、子配置文件启用 二、子配置文件使用 1、创建虚拟主机实验 2、基于端口虚拟主机实验 三、Nginx模块 1、access模块 2、自定义错误页面 3、状态页开启 一、Nginx配置文件 1、主配置文件解析 ①yum安装主配置文件位置&…

docker上发布 sunnyNgrok 实现内外网穿透,容器内执行命令

最近在使用内外网穿透的工具时发现国内版的Ngrok还挺好用的,但是在dockerHub上搜镜像时发现不知道使用哪一个,索性便自己创建一个docker容器。 1、创建自己想要创建docker镜像的文件夹,我创建的名为“sunny-Ngrok” 2、在文件内创建Dockerfi…

【C语言】预处理器

目录 1. 预处理器的工作原理 2. 预处理指令 3. 宏定义 3.1 简单的宏(对象式宏) 3.2 带参数的宏(函数式宏) 3.3 #define替换规则 3.4 #和## 3.5 带副作用的宏参数 3.6 宏和函数对比 3.7 命名约定 3.8 #undef 3.9 预定义…

支持向量机SVM详细原理,Libsvm工具箱详解,svm参数说明,svm应用实例,神经网络1000案例之15

目录 支持向量机SVM的详细原理 SVM的定义 SVM理论 Libsvm工具箱详解 简介 参数说明 易错及常见问题 SVM应用实例,基于SVM的股票价格预测 支持向量机SVM的详细原理 SVM的定义 支持向量机(support vector machines, SVM)是一种二分类模型&a…

Scala面向对象详解(第六章:Scala包、类和对象、封装、继承和多态、抽象、单例、特质)(尚硅谷笔记)

面向对象第 6 章 面向对象6.1 Scala 包6.1.1 包的命名6.1.2 包说明(包语句)6.1.3 包对象6.1.4 导包说明6.2 类和对象6.2.1 定义类6.2.2 属性6.3 封装6.1.5 访问权限6.2.3 方法6.2.4 创建对象6.2.5 构造器6.2.6 构造器参数6.4 继承和多态6.5 抽象类6.5.1 …

基于机器学习的二手车价格预测及应用实现(预测系统实现)

1.摘要 随着中国汽车工业的迅速发展,国内的汽车数量也在迅速增长。新车销售市场已经逐渐饱和,而二手车交易市场正在兴起。但是,由于中国的二手车市场尚未成熟,与发达国家相比仍存在较大差距。其中一个重要原因是二手车的市场价格难…

信息系统项目管理师试题精选(四)

【1】关于区块链的描述,不正确的是( )。A. 区块链的共识机制可有效防止记账节点信息被篡改B. 区块链可在不可信的网络进行可信的信息交换C. 存储在区块链的交易信息是高度加密D. 区块链是一个分布式共享账本和数据库【2】( &#…

记录一次Android视频播放音画不同步问题的定位及分析

1.何为音画不同步 音画不同步很简单就是视频播放过程中声音和画面出现的时间点不一致,滞后或者提前。 2.音画不同步问题分析思路 2.1.音画不同步问题的证明 对于滞后或者提前很多的音画不同步可以直接认为发生了该问题,但是滞后或者提前不是很多的就…

Linux系统安装MySQL8.0版本详细教程【亲测有效】

首先官网下载安装包:https://downloads.mysql.com/archives/community/ 一、上传到安装服务器 二、解压 tar -xvf mysql-8.0.31-linux-glibc2.12-x86_64.tar.xz三、移动位置并重新命名 mv mysql-8.0.31-linux-glibc2.12-x86_64 /usr/local/mysql四、创建mysql用户…

信息安全基础概要(二)——安全保护等级,安全服务与安全机制

目录 一、OSI/RM七层模型 二、各个网络层次的安全保障 三、计算机信息系统安全保护等级划分准则(GB17859-1999) 四、信息安全体系结构——安全服务与安全机制 前篇: https://blog.csdn.net/superSmart_Dong/article/details/125690697 一、OSI/RM七层模型 广播…

每日一题——L1-070 吃火锅(15)

L1-070 吃火锅 分数 15 以上图片来自微信朋友圈:这种天气你有什么破事打电话给我基本没用。但是如果你说“吃火锅”,那就厉害了,我们的故事就开始了。 本题要求你实现一个程序,自动检查你朋友给你发来的信息里有没有 chi1 huo…

字节是真的难进,测开4面终上岸,压抑5个月,终于可以放声呐喊

这次字节的面试,给我的感触很深,意识到基础的重要性。一共经历了五轮面试:技术4面+HR面。 下面看正文 本人自动专业毕业,压抑了五个多月,终于鼓起勇气,去字节面试,下面是我的面试过…

Mysql 索引(二)—— InnoDB 与 MyISAM 索引方式的比较(聚簇索引 VS 非聚簇索引)

在上一部分了解到,主键索引的本质其实就是一棵B树,通过每一层的目录页来找到记录所在的page页。根据 page页是否保存了数据,我们可以将主键索引分为 聚簇索引 和 非聚簇索引。 1、MyISAM (1) 非聚簇索引 非聚簇索引的目录和数据记录是分开存…

NPE:记一次脑残NPE的排查过程

目录 碎碎念: 如下这行报NPE: 排查过程: 解解方案: 小结: 空指针出现的几种情况: 如何从根源避免空指针: 赋值时自动拆箱出现空指针: 1、变量赋值自动拆箱出现的空指针 2、…

接了ChatGPT的NewBing如何评价CodeGeeX

一篇《如何用 CodeGeeX 替代 GitHub Copilot》的文章在开发者社区登上热榜,开发者关注的AI生成代码工具CodeGeeX,这款插件产品目前支持在VSCode市场和Jetbrains IDEs下载使用,是国产对标Copilot目前安装量最大的开发者工具。 之所以引发开发…

JS 中 for in 和 for of 的区别

for in 和 for of 是js中常用的遍历方法;两者的区别如下: 文章目录一,遍历数组二,遍历对象三,总结一,遍历数组 1,for in 是ES5的语法标准,而for of则是ES6语法标准。 const arr1 …