RPC框架源码分析学习(二)

RPC框架源码分析与原理解读

前言

在分布式系统开发中,远程过程调用(RPC)是一项基础且关键的技术。通过对KVstorageBaseRaft-cpp项目RPC模块的源码分析,我深入理解了RPC框架的工作原理和实现细节。本文将从程序员视角分享我的学习心得。

框架概述

本项目中的RPC框架是一个基于Google Protobuf和Muduo网络库实现的C++版RPC框架。它支持服务注册、服务发现和远程方法调用,提供了简洁的接口和高效的数据传输机制。

核心组件分析

1. RPC通信协议

首先,我分析了RPC通信协议的定义文件rpcheader.proto

syntax = "proto3";
package RPC;// RPC请求和响应的消息格式
message RpcHeader {string service_name = 1;  // 服务名string method_name = 2;   // 方法名uint32 args_size = 3;     // 参数大小
}

这个定义非常精简,包含了服务名、方法名和参数大小三个关键信息,这些信息构成了RPC请求的头部。

2. RPC客户端实现

2.1 MprpcChannel类

MprpcChannel是客户端发起RPC调用的核心类,继承自google::protobuf::RpcChannel

class MprpcChannel : public google::protobuf::RpcChannel {
public:// 构造函数,支持立即连接或延迟连接MprpcChannel(string ip, short port, bool connectNow);// 关键方法:负责序列化请求、发送请求并接收响应void CallMethod(const google::protobuf::MethodDescriptor* method,google::protobuf::RpcController* controller,const google::protobuf::Message* request,google::protobuf::Message* response,google::protobuf::Closure* done) override;// 其他辅助方法...
};

CallMethod的实现最为关键,它完成了:

  1. 获取服务名和方法名
  2. 序列化请求参数
  3. 构造RPC请求头
  4. 发送请求并等待响应
  5. 解析响应数据

我特别注意到请求消息格式的设计:

header_size(4字节变长编码) + header_str + args_str

这种设计保证了网络传输的高效性和兼容性。

3. RPC服务端实现

3.1 RpcProvider类

RpcProvider是服务端的核心类,负责服务注册和请求处理:

class RpcProvider {
public:// 注册服务void NotifyService(google::protobuf::Service *service);// 启动RPC服务void Run(int nodeIndex, short port);
private:// 连接回调void OnConnection(const muduo::net::TcpConnectionPtr &);// 消息回调,处理RPC请求void OnMessage(const muduo::net::TcpConnectionPtr &, muduo::net::Buffer *, muduo::Timestamp);// 发送RPC响应void SendRpcResponse(const muduo::net::TcpConnectionPtr &, google::protobuf::Message *);// 其他成员...
};
3.2 服务注册机制

服务注册利用了Protobuf的反射机制,通过NotifyService方法实现:

void RpcProvider::NotifyService(google::protobuf::Service *service) {ServiceInfo service_info;const google::protobuf::ServiceDescriptor *pserviceDesc = service->GetDescriptor();std::string service_name = pserviceDesc->name();int methodCnt = pserviceDesc->method_count();for (int i = 0; i < methodCnt; ++i) {const google::protobuf::MethodDescriptor *pmethodDesc = pserviceDesc->method(i);std::string method_name = pmethodDesc->name();     service_info.m_methodMap.insert({method_name, pmethodDesc});}service_info.m_service = service;m_serviceMap.insert({service_name, service_info});
}

这段代码通过Protobuf的反射机制获取服务描述符和方法描述符,并将它们存储在哈希表中,以便后续查找和调用。

3.3 请求处理流程

OnMessage方法处理接收到的RPC请求:

  1. 解析请求头,获取服务名、方法名和参数大小
  2. 查找对应的服务和方法
  3. 反序列化请求参数
  4. 创建响应对象和回调
  5. 调用目标方法

最关键的部分是动态调用目标方法:

service->CallMethod(method, nullptr, request, response, done);

这里用到了Protobuf的动态调用机制,method是之前通过反射获取的方法描述符,done是一个回调对象,用于处理方法执行完成后的操作。

3.4 回调机制实现

回调函数的创建使用了Protobuf提供的NewCallback模板函数:

google::protobuf::Closure *done =google::protobuf::NewCallback<RpcProvider, const muduo::net::TcpConnectionPtr &, google::protobuf::Message *>(this, &RpcProvider::SendRpcResponse, conn, response);

这段代码创建了一个绑定了当前对象、连接和响应对象的回调函数,在RPC方法执行完成后将被调用,用于发送响应数据。

实例分析:RPC示例代码

通过分析example/rpcExample目录下的示例,进一步理解了RPC框架的使用方法。

1. 服务定义

service FiendServiceRpc {rpc GetFriendsList(GetFriendsListRequest) returns (GetFriendsListResponse);
}

2. 服务实现

class FriendService : public fixbug::FiendServiceRpc {
public:void GetFriendsList(google::protobuf::RpcController* controller,const fixbug::GetFriendsListRequest* request,fixbug::GetFriendsListResponse* response,google::protobuf::Closure* done) override {// 业务逻辑实现response->mutable_result()->set_errcode(0);response->mutable_result()->set_errmsg("");done->Run();  // 调用完成,发送响应}
};

3. 服务注册与启动

int main(int argc, char** argv) {// 创建RPC服务提供者RpcProvider provider;// 创建服务对象FriendService friendService;// 注册服务provider.NotifyService(&friendService);// 启动RPC服务,指定节点ID和端口provider.Run(1, 8000);return 0;
}

技术难点解析

1. 模板与回调函数

RPC框架中大量使用了C++模板和回调函数,这是一个重要的技术点。特别是NewCallback函数的使用:

google::protobuf::NewCallback<Class, ArgType1, ArgType2>(this, &Class::Method, arg1, arg2);

这里模板参数<Class, ArgType1, ArgType2>指定了回调函数的类型和参数类型,而函数参数则提供了具体的对象、方法和参数值。

2. 序列化与网络传输

RPC框架的另一个关键点是如何高效地序列化和网络传输。我分析了其实现方式:

  1. 使用Protobuf进行序列化,保证了跨平台兼容性
  2. 采用"头部大小+头部内容+参数内容"的消息格式,解决了TCP流数据的边界问题
  3. 使用Muduo网络库处理TCP连接和事件回调,提供了高性能的网络IO

2025.5.15

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

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

相关文章

当下流行的智能体通信协议:MCP、A2A、ANP 分别是什么?

在当前人工智能&#xff08;AI&#xff09;智能体生态系统中&#xff0c;智能体之间的有效沟通至关重要。为了让AI智能体能够高效、安全地协同工作&#xff0c;业界提出了多种通信协议。其中&#xff0c;MCP、A2A 和 ANP 代表了三个关键层级的通信协议&#xff0c;各自应对不同…

为什么 cout<<“中文你好“ 能正常输出中文

一, 简答: 受python3字符串模型影响得出的下文C字符串模型结论 是错的&#xff01;C的字符串和python2的字符串模型类似&#xff0c;也就是普通的字符串是ASCII字符串和字节串两种语义&#xff0c;类似重载或多态&#xff0c;有时候解释为整数&#xff0c;有时候是字节串。Uni…

鸿蒙的卓易通,让我踩了一次坑

前言 因为我本身对鸿蒙提不起兴趣&#xff0c;哪怕有些文章给鸿蒙穿上了“黑丝”&#xff0c;再加上公司当前没有适配鸿蒙的计划&#xff0c;所以关于鸿蒙的消息我都关注的很少。 今早&#xff0c;看到了徐宜生老师的一篇文章&#xff1a;“鸿蒙卓易通&#xff0c;是饮鸩止渴…

Cursor vs VS Code vs Zed

代码编辑器的世界已经迎来了创新的爆发。曾经由重量级IDE或基础文本编辑器主导的领域,如今开发者们发现自己正在探索全新一波聚焦于AI集成、协作和性能的工具。 在本文中,我们将深入探讨2025年三款流行的编辑器:Cursor、Visual Studio Code (VS Code)和Zed Code Editor。每…

使用 LiteFlow 实现灵活的业务逻辑解耦

1. 引言 1.1 业务逻辑复杂性带来的挑战 在现代软件开发中,随着业务需求不断增长,代码结构日趋复杂。硬编码式的流程控制方式难以适应频繁变更的需求,导致维护成本高、可读性差、扩展性弱。 1.2 规则引擎在解耦中的作用 规则引擎(Rule Engine)通过将业务逻辑与程序代码…

以项目的方式学QT开发(一)——超详细讲解(120000多字详细讲解,涵盖qt大量知识)逐步更新!

以项目的方式学QT开发 以项目的方式学QT开发 P1 QT介绍 1.1 QT简介 1.2 QT安装 1.2.1 Windows QT安装 1.2.2 QT Creator 使用基本介绍 P2 C基础 2.1 命名空间 2.1.1 命名空间作用 2.1.2 自定义命名空间 2.2 从C语言快速入门 2.2.1 输入输出 2.2.2 基…

【前端】【css】【总复习】三万字详解CSS 知识体系

&#x1f308; CSS 知识体系目录大纲 一、基础知识入门 1. CSS 简介与作用 CSS&#xff08;Cascading Style Sheets&#xff0c;层叠样式表&#xff09;是一种用于给 HTML 页面添加样式的语言&#xff0c;作用是让网页更美观、结构更清晰、布局更灵活。 核心作用&#xff1a;…

R利用spaa包计算植物/微生物的生态位宽度和重叠指数

一、生态位宽度 生态位宽度指数包括shannon生态位指数和levins生态位指数。下面是采用levins方法计算生态位宽度。method也可以选择“shannon”。 二、生态位重叠指数 生态位重叠指数&#xff0c;包括levins生态位重叠指数、schoener生态位重叠指数、petrai…

【论信息系统项目的合同管理】

论信息系统项目的合同管理 论文要求写作要点正文前言一、合同的签订管理二、合同履行管理三、合同变更管理四、合同档案管理五、合同违约索赔管理结语 论文要求 项目合同管理通过对项目合同的全生命周期进行管理&#xff0c;来回避和减轻可识别的项目风险。 请以“论信息系统项…

最新网盘资源搜索系统,电视直播,Alist聚合播放

源码描述&#xff1a; 本项目是基于Vue与Nuxt.js技术构建的网盘搜索项目&#xff0c;持续开源并维护更新。该项目旨在使每个人都能拥有属于自己的网盘搜索网站。我们强烈建议用户自行部署该项目。 更新日志&#xff1a; 新增TV播放功能新增Alist源聚合播放功能新增批量删除功…

【Ubuntu】安装BitComet种子下载器

环境 Ubuntu 24.04.2 下载依赖库 环境比较新&#xff0c;此软件需要依赖很多旧的库&#xff0c;逐个安装下载&#xff1a; 1.libicu70 http://nz.archive.ubuntu.com/ubuntu/pool/main/i/icu/libicu70_70.1-2_amd64.deb2.libjavascriptcoregtk-4.0-18 http://security.ubu…

修复“ImportError: DLL load failed while importing lib: 找不到指定的程序”笔记

#工作记录 一、问题描述 在运行CosyVoice_For_Windows项目时&#xff0c;出现以下报错&#xff1a; Traceback (most recent call last): File "D:\ProgramData\anaconda3\envs\CosyVoice\Lib\pydoc.py", line 457, in safeimport module __import__(path) …

ubuntu18 设置静态ip

百度 编辑/etc/netplan/01-netcfg.yaml 系统没有就自己编写 network: version: 2 renderer: networkd ethernets: eth0: dhcp4: no addresses: [192.168.20.8/24] # 设置你的IP地址和子网掩码 gateway4: 192.168.20.1 # 网关地址 namese…

帧差法识别

定义&#xff1a; 视频通过闪过x帧画面来实现&#xff0c;帧差法就是利用两帧之间的差异找出。也就是移动目标识别 帧差法识别步骤&#xff1a; 1、灰度处理&#xff1a;将多通道变成双通道压缩图像数据。 cvtColor(before_frame,before_gray,CV_RGB2GRAY);cvtColor(after_f…

基于OAuth2+SpringSecurity+Jwt实现身份认证和权限管理后端服务

1、简介 本文讲述了如何实现简易的后端鉴权服务。所谓“鉴权”&#xff0c;就是“身份鉴定”“权限判断”。涉及的技术有&#xff1a;OAuth2、SpringSecurity、Jwt、过滤器、拦截器。OAuth2用于授权&#xff0c;使用Jwt签发Access Token和Refresh Token&#xff0c;并管理token…

<C++> MFC自动关闭对话框(MessageBoxTimeout)

MFC自动关闭对话框&#xff08;MessageBoxTimeout&#xff09; 记录一下今天在界面开发中的解决方案。自动关闭对话框有两种方案&#xff1a; 1.使用定时器实现延迟关闭&#xff08;DeepSeek方案&#xff09; 提示框显示几秒后自动关闭&#xff0c;可以使用 SetTimer KillT…

多语言支持的常见设计方案

在 Java 项目中实现**多语言&#xff08;国际化&#xff0c;i18n&#xff09;**功能&#xff0c;是很多企业级应用支持不同地区和语言用户的基础需求。以下是 Java 中实现多语言支持的常见设计方案&#xff1a; 一、常见多语言设计方案 1. 使用 ResourceBundle 读取 propertie…

vuex基本介绍

Vuex是Vue.js应用程序中专门用于状态管理的库。以下是其基本介绍&#xff1a; 概念 Vuex采用集中式存储管理应用的所有组件的状态&#xff0c;并以相应的规则保证状态以一种可预测的方式发生变化。 特点 - 集中化管理&#xff1a;将应用的状态集中存储在一个单一的状态…

Android开发-在应用之间共享数据

在Android系统中&#xff0c;应用之间的隔离机制&#xff08;沙箱机制&#xff09;保障了系统的安全性与稳定性。然而&#xff0c;在实际开发中&#xff0c;我们经常需要实现跨应用的数据共享&#xff0c;例如&#xff1a; 从一个应用向另一个应用传递用户信息&#xff1b;多个…

深度解析 JWT:从原理到实战的全场景解决方案(附永久 Token 设计与集成系统实践)

摘要 本文结合 JWT 官方标准&#xff08;RFC 7519&#xff09;与生产级实践&#xff0c;全面解析 JSON Web Token 的核心机制、安全规范及 Java 生态最佳实现。涵盖 JJWT 工具类优化、Auth0/Nimbus 替代方案对比、永久 Token 设计&#xff08;满足集成系统长期调用需求&#x…