🔥 RPC(Remote Procedure Call)
远程过程调用,是一种通过网络从远程计算机上请求服务,而不需要了解底层网络通信细节。
RPC
可以使用多种网络协议进行通信,如HTTP、TCP、UDP等,并且在 TCP/IP
网络四层模型中跨越了传输层和应用层。简言之RPC就是像调用本地方法一样调用远程方法💬 通俗类比:通信方式的进化
+ 本地调用:情侣同城约会
- 随时见面(低延迟)
- 直接交流(无需协议)
+ RPC调用:跨国网恋奔现
✈️ 约定时间(服务发现)
📨 发送航班信息(序列化)
🛃 海关检查(协议校验)
💌 最终见面(反序列化)
一个完整RPC通信框架,大概包含以下内容
我们的项目是基于C++、JsonCpp、muduo网络库实现一个简单、易用的RPC通信框架,即使是不懂网络的开发者也可以很快速的上手,它实现了同步调用、异步
callback
调用、异步futrue
调用、服务注册/发现,服务上线/下线以及发布订阅等功能设计。
目前RPC的实现方案有两种:
client
和 server
继承公共接口
IDL
(接口描述语言)定义公共接口原理
protobuf
是一种高效的序列化协议,支持通过 .proto
文件定义数据结构。protobuf
提供了反射机制,允许程序在运行时动态获取消息的字段信息(如字段名、类型等)。通过反射机制,可以将网络传输的参数和返回值动态映射到对应的RPC接口。
实现步骤
.proto
文件 :描述RPC接口的请求和响应数据结构。protoc
工具生成对应语言的代码(如C++、Python等)。优点
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 图
由于前两种技术难度和学习成本较高,因此这个项目我们使用第三种方式
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.repo
sudo 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-devel
ls /usr/include/jsoncpp/json/
assertions.h autolink.h config.h ...
⑧ 安装 cmake
sudo yum install cmake
cmake --version
cmake version 2.8.12.2
⑨ 安装 Muduo
# git⽅式
[zsc@node ~]$ git clone https://github.com/chenshuo/muduo.git
sudo yum install make boost-devel
安装依赖环境
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.list
deb 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 make
sudo 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