📃個人主頁:island1314
🔥個人博客:island
?? 歡迎關注:👍點贊 👂🏽留言 😍收藏 💞 💞 💞
- 生活總是不會一帆風順,前進的道路也不會永遠一馬平川,如何面對挫折影響人生走向 – 《人民日報》
🔥 目錄
- 一、項目介紹
- 二、技術選型
- 2.1 RPC 實現方案
- 2.2 網絡傳輸的參數和返回值怎么映射到對應的RPC接口上?
- 方法一:使用 protobuf 的反射機制
- 方法二:使用 C++ 模板、類型萃取、函數萃取等機制
- 方法三:使用更通用的類型(如 JSON)
- 🌈 技術方案對比
- 2.3 網絡傳輸怎么做?
- 2.4 序列化和反序列化?
- 三、環境搭建
- 3.1 Centos 7.6 環境搭建
- 3.2 Ubuntu 22.04 環境搭建
一、項目介紹
🔥 RPC(Remote Procedure Call)
遠程過程調用,是一種通過網絡從遠程計算機上請求服務,而不需要了解底層網絡通信細節。
RPC
可以使用多種網絡協議進行通信,如HTTP、TCP、UDP等,并且在TCP/IP
網絡四層模型中跨越了傳輸層和應用層。簡言之RPC就是像調用本地方法一樣調用遠程方法- 過程可以理解為業務處理、計算任務,更直白的說,就是程序/方法/函數等,就是像調用本地方法一樣調用遠程方法
💬 通俗類比:通信方式的進化
+ 本地調用:情侶同城約會- 隨時見面(低延遲)- 直接交流(無需協議)+ RPC調用:跨國網戀奔現 ?? 約定時間(服務發現)📨 發送航班信息(序列化)🛃 海關檢查(協議校驗)💌 最終見面(反序列化)
一個完整RPC通信框架,大概包含以下內容
- 序列化協議
- 通信協議
- 連接復用
- 服務注冊
- 服務發現
- 服務訂閱和通知
- 負載均衡
- 服務監控
- 同步調用
- 異步調用
我們的項目是基于C++、JsonCpp、muduo網絡庫實現一個簡單、易用的RPC通信框架,即使是不懂網絡的開發者也可以很快速的上手,它實現了同步調用、異步
callback
調用、異步futrue
調用、服務注冊/發現,服務上線/下線以及發布訂閱等功能設計。
二、技術選型
2.1 RPC 實現方案
目前RPC的實現方案有兩種:
-
client
和server
繼承公共接口- 根據
IDL
(接口描述語言)定義公共接口 - 編寫代碼生成器根據IDL語言生成相關的C++、Java代碼然后我們的客戶端和服務器程序共同向上繼承公共接口即可
- 比如:我們常用的Protobuf、ison可以定義IDL接口,并生成RPC相關的代碼
- 缺點:使用pb因為生成一部分代碼,所以對理解不夠友好;如果是json定義IDL語言 需要自己編寫代碼生成器難度較大一點,暫不考慮這種方案
- 根據
-
實現?個遠程調用接口cal,,然后通過傳入函數名參數來調用RPC接口,我們采用這種實現方案
2.2 網絡傳輸的參數和返回值怎么映射到對應的RPC接口上?
方法一:使用 protobuf 的反射機制
原理
protobuf
是一種高效的序列化協議,支持通過 .proto
文件定義數據結構。protobuf
提供了反射機制,允許程序在運行時動態獲取消息的字段信息(如字段名、類型等)。通過反射機制,可以將網絡傳輸的參數和返回值動態映射到對應的RPC接口。
實現步驟
- 定義
.proto
文件 :描述RPC接口的請求和響應數據結構。 - 生成代碼 :使用
protoc
工具生成對應語言的代碼(如C++、Python等)。 - 利用反射機制 :
- 在運行時,通過反射機制解析請求和響應的字段。
- 動態調用對應的RPC接口,并將解析后的數據作為參數傳遞。
- 序列化和反序列化 :將請求和響應數據序列化為二進制格式進行傳輸。
優點
- 高效:
protobuf
序列化效率高,占用帶寬小。 - 強類型:編譯時檢查字段類型,減少運行時錯誤。
- 易擴展:通過
.proto
文件輕松擴展字段。
缺點
- 學習成本較高:需要熟悉
.proto
文件和反射機制。 - 動態性有限:反射機制雖然靈活,但仍需依賴預定義的
.proto
文件。
Mermaid 圖
方法二:使用 C++ 模板、類型萃取、函數萃取等機制
原理
C++ 模板元編程允許在編譯時對類型進行操作,而類型萃取和函數萃取則用于提取函數的參數和返回值類型。通過這些機制,可以在編譯時自動推導出RPC接口的參數和返回值類型,從而實現參數和返回值的映射。
實現步驟
- 定義RPC接口 :使用C++函數定義RPC接口。
- 使用模板萃取 :
- 利用
std::function
或模板函數提取函數的參數和返回值類型。 - 定義通用的包裝器(Wrapper),將參數和返回值映射到網絡傳輸的格式。
- 利用
- 序列化和反序列化 :
- 將參數序列化為網絡傳輸格式(如JSON或自定義二進制格式)。
- 在服務端反序列化后,調用對應的RPC接口。
- 返回結果 :將返回值序列化并發送回客戶端。
優點
- 高性能:所有類型推導和映射在編譯時完成,運行時開銷低。
- 靈活性強:支持任意類型的參數和返回值。
- 類型安全:編譯時檢查參數和返回值類型。
缺點
- 復雜度高:需要熟悉C++模板元編程和類型萃取機制。
- 不易調試:模板代碼在編譯時展開,調試難度較大。
MerMaid 圖
方法三:使用更通用的類型(如 JSON)
原理
JSON 是一種輕量級的數據交換格式,具有良好的可讀性和跨語言支持。通過設計一套通用的參數和返回值協議,可以將網絡傳輸的數據統一表示為JSON格式,從而簡化參數和返回值的映射。
實現步驟
- 設計協議 :
- 定義請求和響應的JSON結構,包括字段名、類型和含義。
- 例如,請求可能包含
method
(接口名)、params
(參數列表)等字段。
- 序列化和反序列化 :
- 客戶端將參數序列化為JSON格式并發送。
- 服務端解析JSON數據,提取參數并調用對應的RPC接口。
- 返回結果 :
- 服務端將返回值序列化為JSON格式并發送回客戶端。
優點
- 簡單易用:JSON格式直觀,易于理解和實現。
- 跨語言支持:幾乎所有的編程語言都支持JSON解析。
- 動態性強:無需提前定義固定的數據結構。
缺點
- 性能較低:JSON序列化和反序列化效率低于二進制格式。
- 類型不安全:JSON是弱類型格式,可能導致運行時錯誤。
MerMaid 圖
🌈 技術方案對比
方案 | 核心技術 | 優點 | 缺點 |
---|---|---|---|
Protobuf反射 | 利用.proto 文件的元數據描述 | 強類型安全,跨語言支持 | 需要IDL編譯,C++實現較復雜 |
模板元編程 | 類型萃取+函數簽名解析 | 零運行時開銷,類型嚴格匹配 | 代碼可讀性差,調試困難 |
JSON通用協議 | 動態類型系統+預定義協議格式 | 開發簡單,易擴展,可視化調試 | 類型安全性需運行時校驗 |
- 由于前兩種技術難度和學習成本較高,因此這個項目我們使用第三種方式
2.3 網絡傳輸怎么做?
- 原生socket :實現難度較大,暫不考慮
- Boost asio庫的異步通信:需要擴展boost庫
- muduo庫:和當前項目對應,學習開發成本較低
2.4 序列化和反序列化?
Protobuf
:可選JSON
:因為項目需要使用JSON
來定義函數參數和返回值,所以項目中直接采用JSON
進行序列化和反序列化
三、環境搭建
3.1 Centos 7.6 環境搭建
① 安裝 wget
sudo yum install wget
② 更新軟件源
sudo mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak
sudo wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.reposudo yum clean all # 清理緩存信息
sudo yum makecache
③ 安裝 scl 軟件源
sudo yum install centos-release-scl-rh centos-release-scl
④ 安裝 epel 軟件源
sudo yum install epel-release
⑤ 安裝 lrzsz 傳輸工具
sudo yum install lrzsz
rz --version
rz (lrzsz) 0.12.20
⑥ 安裝高版本 gcc/g++ 編譯器
sudo yum install devtoolset-7-gcc devtoolset-7-gcc-c++
echo "source /opt/rh/devtoolset-7/enable" >> ~/.bashrc
source ~/.bashrc
g++ -v
⑦ 安裝 Jsoncpp 庫
sudo yum install jsoncpp-devells /usr/include/jsoncpp/json/
assertions.h autolink.h config.h ...
⑧ 安裝 cmake
sudo yum install cmakecmake --version
cmake version 2.8.12.2
⑨ 安裝 Muduo
- 下載源碼
# git?式
[zsc@node ~]$ git clone https://github.com/chenshuo/muduo.git
- 修復 muduo 庫 安裝 protorpc 的時候沒有安裝
/muduo-master/muduo/net/protorpc/CMakeLists.txt
- 安裝依賴環境
sudo yum install make boost-devel
當前上面步驟還是過于多了,我們可以直接 運行腳本編譯安裝
腳本鏈接:https://gitee.com/qigezi/bitrpc/blob/master/third/muduo-master.zip
然后把腳本下載之后導入解包,按照下面指令編譯安裝即可
./build.sh
./build.sh install
3.2 Ubuntu 22.04 環境搭建
① 安裝 wget – 一般默認情況下都有
sudo apt-get install wget
② 更新國內軟件源
先備份原來的 /etc/apt/source.list 文件
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak# 比如
lighthouse@VM-8-10-ubuntu:~$ sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
lighthouse@VM-8-10-ubuntu:~$ ls /etc/apt/
apt.conf.d keyrings sources.list sources.list.curtin.old trusted.gpg.d
auth.conf.d preferences.d sources.list.bak sources.list.d
添加軟件源文件內容,新增以下內容
# 先打開源文件
sudo vi /etc/apt/source.listdeb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse
#添加清華源
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-backports main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-security main restricted universe multiverse
新增完畢后,更新源
sudo apt-get update
③ 安裝 lrzsz 傳輸工具
sudo apt-get install lrzsz
rz --version
rz (lrzsz) 0.12.20
④ 安裝高版本 gcc/g++ 編譯器
sudo apt-get install gcc g++
⑤ 安裝項目構建工具 make 和 cmake
sudo apt-get install makesudo apt-get install cmake
cmake --version
cmake version 3.22.1
⑥ 安裝調試器 gdb
sudo apt-get install gdb
⑦ 安裝 git
sudo apt-get install git
git --versio
⑧ 安裝 Jsoncpp 庫
sudo apt-get install libjsoncpp-dev# 安裝成功之后
ls /usr/include/jsoncpp/json/
allocator.h config.h json_features.h reader.h version.h
assertions.h forwards.h json.h value.h writer.h
⑨ 安裝 Muduo
- 下載源碼
# git?式
[zsc@node ~]$ git clone https://github.com/chenshuo/muduo.git
- 安裝依賴環境
sudo apt-get install libz-dev libboost-all-dev
運行腳本編譯安裝
unzip muduo-master.zip
./build.sh
./build.sh install
參考
https://zhuanlan.zhihu.com/p/460646015
https://zhuanlan.zhihu.com/p/33298916
源碼:https://github.com/cinemast/libjson-rpc-cpp
value.h writer.h
⑨ 安裝 Muduo- 下載源碼 ```bash
# git?式
[zsc@node ~]$ git clone https://github.com/chenshuo/muduo.git
- 安裝依賴環境
sudo apt-get install libz-dev libboost-all-dev
運行腳本編譯安裝
unzip muduo-master.zip
./build.sh
./build.sh install
參考
https://zhuanlan.zhihu.com/p/460646015
https://zhuanlan.zhihu.com/p/33298916
源碼:https://github.com/cinemast/libjson-rpc-cpp
源碼:https://github.com/qicosmos/rest_rpc