RPC 和 序列化
RPC
1 RPC调用流程
1.1 clerk客户端调用远程服务
Clerk::PutAppend()
raftServerRpcUtil::PutAppend()
raftServerRpcUtil是client与kvserver通信的入口, 包含kvserver功能的一对一映射:Get/PutAppend,通过stub对象——raftKVRpcProctoc::kvServerRpc_Stub *stu进行对应的rpc远程调用。
针对raft节点之间的通信,设计了RaftRpcUtil类型,包含raft节点功能:AppendEntries/ InstallSnapshot/ RequestVote
kvServerRpc_Stub::PutAppend()
kvServerRpc_Stub 是 kvServerRPC.proto文件编译后生成的存根,用于实现rpc远程调用。
stub使用MprpcChannel作为参数来初始化,因此接下来会调用MprpcChannel::CallMethod():
stub = new raftKVRpcProctoc::kvServerRpc_Stub(new MprpcChannel(ip, port, false));
MprpcChannel::CallMethod()
MprpcChannel:实现rpc通信的类,建立和服务端的连接,发送rpc请求,和接收rpc回复
所有通过stub调用的rpc方法,都会走到MprpcChannel::CallMethod(): 生成rpc请求数据并序列化,使用socket发送请求并接收回复
1.2 kvserver 提供rpc服务
KvServer::KvServer()
构造函数中发布rpc服务类型: 服务的类型有两种,分别是Raft和KvServer:
- class Raft : public raftRpcProctoc::raftRpc
- class KvServer : raftKVRpcProctoc::kvServerRpc
Raft类型的服务用于raft节点之间相互调用,KvServer类型的服务被client调用
RpcProvider::Run() 启动rpc服务,等待调用。项目中是阻塞等待,同步阻塞模型。
RpcProvider::OnMessage()
已建立连接用户的读写事件回调:调用Callmethod来调用本地的业务
RpcProvider:网络对象类,发布节点能提供的rpc服务,并启动rpc服务(接收连接,接收请求并执行)
service->CallMethod()
有两种服务类型(Raft和KvServer),根据请求的service的类型,动态调用对应的CallMethod();
client调用 KvServerRpc::CallMethod(),raft节点调用raftRpc::CallMethod()。
KvServerRpc::CallMethod()
在函数内部,最终调用KvServer本地的方法。
2 rpc基础
2.1 概念
- RPC(Remote Procedure Call Protocol) 远程过程调用协议。
- RPC是一种通过网络从远程计算机上请求服务,不需要了解底层网络技术的协议。
- 远程调用就像调用本地方法一样便捷。
2.2 常用RPC技术或框架
- 应用级的服务框架:阿里的 Dubbo/Dubbox、Google gRPC、Spring Boot/Spring Cloud。
- 远程通信协议:RMI、Socket、SOAP(HTTP XML)、REST(HTTP JSON)。
- 通信框架:MINA 和 Netty
2.3 rpc作用
- 微服务化:跨平台的服务之间远程调用;
- 分布式系统架构:分布式服务跨机器进行远程调用;
- 支持跨语言调用。
2.4 架构

服务注册,就是将提供某个服务的模块信息(通常是这个服务的ip和端口)注册到1个公共的组件上去(注册中心,比如: zookeeper\consul)。
服务发现,就是新注册的这个服务模块能够及时的被其他调用者发现。不管是服务新增和服务删减都能实现自动发现。
一个完整的服务发现中心还需要支持负载均衡、容灾处理等功能。
负载均衡:简单数就是将请求分散给各个机器上,维持各个机器的请求的均衡态势。确保不会大量请求都涌入到某几个机器上导致机器过载。
容灾处理:就是及时剔除掉故障的机器。例如某次调用19.4.11.11上的OrderServer出现故障,那么服务中心会将这个地址剔除掉,防止下次再访问到这个有故障的地址。
2.5 rpc调用流程

2.6 重要组成
客户端:调用方
客户端存根:client stub,保存服务端地址信息,将客户端的请求方法、参数序列化,通过网络发送给服务端。
服务端存根:server stub,接收请求,反序列化,调用本地服务
服务端:服务提供者
网络传输:tcp或http
2.7 基础功能
2.7.1 服务寻址
rpc所有函数都有一个自己的ID,在所有进程中都唯一。客户端远程调用,必须附上这个ID.
客户端查一下映射表,找出对应ID,服务端根据对应的ID提供服务。
Call ID映射表一般是哈希表。
2.7.2 序列化和反序列化
概念
- 序列化:将消息对象转换为二进制流。
- 反序列化:将二进制流转换为消息对象。
必要性
- 本地函数调用:只需要将数据压入栈中,然后让函数去栈中读取数据。
- 远程调用:无法通过栈传递参数。需要客户端将请求序列化,传送给服务端。
序列化的优势
- 二进制字节流便于网络传输
- 可跨平台、跨语言。
2.7.3 网络传输
基于TCP
通过socket连接发送序列化的调用接口名称、方法名称和参数等。
基于HTTP
客户端发送GET/PUT/POST/DELETE请求给服务端
服务端根据不同的请求参数和请求url进行方法调用,返回结果
对比
基于TCP更灵活,可减少网络开销,性能高。但实现复杂;
HTTP已经实现序列化,但http传输效率比tcp低。
2.8 服务治理
2.8.1 负载均衡
本项目实现的rpc没有做负载均衡,因为当前是Read Log模式,读写请求都是直接发送给leader。后面如果优化为从follower读,可能用得到负载均衡。
- 轮询算法(Round Robin):轮询算法是最简单的负载均衡算法之一,它按照请求的顺序依次将每个请求分配到不同的服务器上。当有新的请求到来时,负载均衡器会依次将请求发送到不同的服务器,直到所有的服务器都被轮询过一遍,然后再从头开始。
- 最小连接数算法(Least Connections):最小连接数算法会将新的请求分配到当前连接数最少的服务器上,以确保各服务器的负载尽可能均衡。这种算法考虑了服务器的负载情况,优先将请求发送到负载较低的服务器上。
- 最少响应时间算法(Least Response Time):最少响应时间算法会将请求发送到响应时间最短的服务器上,以保证响应时间的最小化。这种算法通常需要负载均衡器记录每个服务器的响应时间,并动态调整请求的分配策略。
- 哈希算法(Hashing):哈希算法根据请求的某些属性(如客户端IP地址、URL等)计算哈希值,并将请求发送到对应哈希值的服务器上。这种算法能够确保相同请求始终被发送到同一台服务器上,适用于需要保持会话一致性的场景。
- 加权轮询算法(Weighted Round Robin):加权轮询算法在轮询算法的基础上引入了权重的概念,不同的服务器具有不同的权重值。根据权重值的不同,负载均衡器会调整请求的分配比例,以实现负载均衡。
- 拓展:hash环也是一种重要的负载均衡算法,也可以提及。
3 本项目rpc
本项目实现的rpc比较简单,采用的是同步阻塞模式。
rpc请求格式:
- head_size(4个字节,存储head_str的长度)
- head_str(RpcHeader类型的序列化)
- args(PutAppendArgs/GetArgs 请求对象的序列化)
RpcHeader:
message RpcHeader
{bytes service_name = 1;bytes method_name = 2;uint32 args_size = 3;
}
可以优化的点:
- 异步rpc
- rpc设为长连接还是短连接?长连接考虑设计一个定时器
- 负载均衡
- 服务发现,服务注册
序列化
1 Protobuf
kvServerRPC.proto文件
syntax = "proto3";
package raftKVRpcProctoc; //所在的命名空间
option cc_generic_services = true; //开启stub服务message GetArgs{bytes Key = 1 ;bytes ClientId = 2 ;int32 RequestId = 3;
}
message GetReply {bytes Err = 1;bytes Value = 2;
}message PutAppendArgs {bytes Key = 1;bytes Value = 2 ;bytes Op = 3;bytes ClientId = 4;int32 RequestId = 5;
}
message PutAppendReply {bytes Err = 1;
}service kvServerRpc
{rpc PutAppend(PutAppendArgs) returns(PutAppendReply);rpc Get (GetArgs) returns (GetReply);
}
.proto文件定义message类型和service类型,编译后,生成.pb.h文件和.pb.cc文件。
.proto文件中定义的message类型可以序列化和反序列化(SerializeToString/ParseFromString).
编译后会生成对应Stub(存根)类型 raftKVRpcProctoc::kvServerRpc_Stub,使用Stub对象可以调用.proto文件中定义的service。
2 boost
快照:kvserver、kvdb和raft节点使用boost库进行序列化
相关文章:
RPC 和 序列化
RPC 1 RPC调用流程 1.1 clerk客户端调用远程服务 Clerk::PutAppend() raftServerRpcUtil::PutAppend() raftServerRpcUtil是client与kvserver通信的入口, 包含kvserver功能的一对一映射:Get/PutAppend,通过stub对象——raftKVRpcProctoc:…...
【原创】三十分钟实时数据可视化网站前后端教程 Scrapy + Django + React 保姆级教程向
这个本来是想做视频的,所以是以讲稿的形式写的。最后没做视频,但是觉得这篇文还是值得记录一下。真的要多记录,不然一些不常用的东西即使做过几个月又有点陌生了。 文章目录 爬虫 SCRAPYxpath 后端 DJANGO前端 REACT Hello大家好这里是小鱼&a…...
MySQL的备份
为什么要备份: 1.保证重要的数据不丢失 2.数据转移 MySQL数据库备份的方式: 1.直接拷贝物理文件 2.在可视化工具中手动导出 (1)在想要导出的表或者数据库中,右键,选择备份或导出 使用命令行导出 MyS…...
Linux 磁盘的一生
注意:实验环境都是使用VMware模拟 磁盘接口类型这里vm中是SCSI,扩展sata,ide(有时间可以看看或者磁盘的历史) 总结:磁盘从有到无—类似于建房子到可以住 ————————————————————————————————————…...
C#配置连接数据库字段
在Web.config文件中 添加如下配置 <!--连接数据库字段--><connectionStrings><add name"sql" connectionString"server.;uidsa;pwd8888;databaseArticleWebSite" /></connectionStrings>...
QCOM和其他常见芯片平台术语缩写
1 QCOM 1.1 General Qualcomm: Quality Communications ALSA DCP:ALSA由DAI、Codec、Platform三部分组成 ALSA TLV:Type-Length-Value Alternative Mode: 替代模式 ANC:Automatic Noise Canceller ASM: Anntena Switch Module AT:…...
css页面布局
CSS属性书写顺序(重点) 建议遵循以下顺序: 布局定位属性:display / position/ float / clear / visibility / overflow(建议display第一个写,毕竟关系到模式) 自身属性:width / height / margin / padding / border / background…...
6、Design Script之列表
Range 在DesignScript中,Range是从起点到终点的一系列数字,使用指定的步距(间距类型),并有以下的初始化方法: start..end..step; start..end..#amount; start..end..~approximate; Range可以是数字的,也可以是字母的。 字母范围因大小写而异。 开始,结束. .#数量范围(…...
Mysql数据库的多实例部署
mysql多实例部署 先进行软件下载 上传二进制格式的mysql软件包 [rootcjy ~]# ls anaconda-ks.cfg mysql-8.0.35-linux-glibc2.28-x86_64.tar.xz配置用户和组并解压二进制程序至/usr/local下 创建用户和组 [rootcjy ~]# useradd -r -s /sbin/nologin -M mysql解压软件至/usr…...
陈巍:Sora大模型技术精要万字详解(上)——原理、关键技术、模型架构详解与应用
目录 收起 1 Sora的技术特点与原理 1.1 技术特点概述 1.2 时间长度与时序一致性 1.3 真实世界物理状态模拟 1.4 Sora原理 1.4.1扩散模型与单帧图像的生成 1.4.2 Transformer模型与连续视频语义的生成 1.4.3 从文本输入到视频生成 2 Sora的关键技术 2.1 传统文生图技…...
JS原型和原型链的理解
原型链图,图中Parent是构造函数,p1是通过Parent实例化出来的一个对象 前置知识 js中对象和函数的关系,函数其实是对象的一种 函数、构造函数的区别,任何函数都可以作为构造函数,但是并不能将任意函数叫做构造函数&…...
力扣题单(小白友好)
力扣题单 算法小白自用题单,目前对于一些简单的数据结构感觉掌握的还可以,但是力扣很多题还是需要看题解,不够熟练;故整理了一份题单,用于巩固练习; 网上确实有很多对于算法分类讲解的网站,but:有一丢丢选择困难症,每天不知道该刷什么题,再加上网站对于一类题一般就有十几道题目…...
王道c语言ch11-单链表的新建、插入、删除例题
王道c语言ch11-单链表的新建、插入、删除例题 #include <stdio.h> #include <stdlib.h> #define END 33typedef int ElemType;typedef struct LNote {ElemType data;struct LNote *next; } LNote, *LinkList;//头插法 void list_head_insert(LinkList &L) {El…...
蓝桥杯刷题--python-23
2.危险系数 - 蓝桥云课 (lanqiao.cn) n, m map(int, input().split()) map_ [[] for i in range(n 1)] used [0 for i in range(n 1)] used_ [0 for i in range(n 1)] cnt 0 res [] for _ in range(m):u, v map(int, input().split())map_[u].append(v)map_[v].appen…...
蓝桥杯刷题--python-24
0地图 - 蓝桥云课 (lanqiao.cn) from math import * import sys from functools import lru_cache # sys.setrecursionlimit(100000) n, m, k map(int, input().split()) a [input() for i in range(n)] dr [(0, 1), (1, 0)] cnt 0 lru_cache(maxsizeNone) def dfs(x, y, …...
面向对象(C# )
面向对象(C# ) 文章目录 面向对象(C# )ref 和 out传值调用和引用调用ref 和 out 的使用ref 和 out 的区别 结构体垃圾回收GC封装成员属性索引器静态成员静态类静态构造函数拓展方法运算符重载内部类和分布类 继承里氏替换继承中的…...
Lombok:@Cleanup资源释放利器
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 一、Cleanup介绍 二、使用示例 三、价值阐述 总结 提示:以下是本篇文章正文内容,下面案例可供参考 一、Cleanup介绍 Cleanup可以自动管理输…...
IoT 物联网场景中 LoRa + 蓝牙Bluetooth 室内场馆高精定位技术全面解析
基于LoRa蓝牙的室内场景定位技术,蓝牙主要负责位置服务,LoRa主要负责数据传输。 01 LoRa和蓝牙技术 LoRa全称 “Long Rang”,是一种成熟的基于扩频技术的低功耗、超长距离的LPWAN无线通信技术。LoRa主要采用的是窄带扩频技术,抗干…...
SpringCloudAlibaba系列之Seata实战
目录 环境准备 1.下载seata安装包 2.修改配置文件 3.准备seata所需配置文件 4.初始化seata所需数据库 5.运行seata 服务准备 分布式事务测试 环境准备 1.下载seata安装包 Seata-Server下载 | Apache Seata 本地环境我们选择稳定版的二进制下载。 下载之后解压到指定目录…...
蓝桥杯day5刷题日记-分巧克力-天干地支-求和
P8647 [蓝桥杯 2017 省 AB] 分巧克力 思路:二分查找 #include <iostream> using namespace std; int n,k; int h[100010],w[100010];bool check(int x) {int sum0;for(int i0;i<n;i){sum(h[i]/x)*(w[i]/x);if(sum>k) return true;}return false; }int…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
Python 高效图像帧提取与视频编码:实战指南
Python 高效图像帧提取与视频编码:实战指南 在音视频处理领域,图像帧提取与视频编码是基础但极具挑战性的任务。Python 结合强大的第三方库(如 OpenCV、FFmpeg、PyAV),可以高效处理视频流,实现快速帧提取、压缩编码等关键功能。本文将深入介绍如何优化这些流程,提高处理…...
客户案例 | 短视频点播企业海外视频加速与成本优化:MediaPackage+Cloudfront 技术重构实践
01技术背景与业务挑战 某短视频点播企业深耕国内用户市场,但其后台应用系统部署于东南亚印尼 IDC 机房。 随着业务规模扩大,传统架构已较难满足当前企业发展的需求,企业面临着三重挑战: ① 业务:国内用户访问海外服…...
动态生成element-plus的scss变量;SCSS中实现动态颜色变体生成
文章目录 一、动态css变量1.生成内容2.动态生成css变量2.1新增_color-utils.scss(不推荐)2.2新增_color-utils.scss(推荐)2.3theme.scss引入使用 一、动态css变量 1.生成内容 在我们修改element-plus主题色时候,会自…...
git引用概念(git reference,git ref)(简化对复杂SHA-1哈希值的管理)(分支引用、标签引用、HEAD引用、远程引用、特殊引用)
文章目录 **引用的本质**1. **引用是文件**2. **引用的简化作用** **引用的类型**1. **分支引用(Branch References)**2. **标签引用(Tag References)**3. **HEAD 引用**4. **远程引用(Remote References)*…...
