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.pswp.cn/diannao/83138.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/83138.shtml
英文地址,請注明出處:http://en.pswp.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…