C++远程调用组件库JsonRpc(一)项目背景、核心概念与环境搭建

C++远程调用组件库JsonRpc(一)项目背景、核心概念与环境搭建


项目背景和意义

假设我们正在写一个分布式系统,部署在两台服务器上:

  • 服务器A:跑着AI模型推理服务(GPU服务器,算力强)
  • 服务器B:跑着Web后端(处理用户请求、管理会话、查数据库)

现在有一个需求:用户发一条消息,服务器B需要调用服务器A上的模型来生成回复。

  • 你会怎么做?

最原始的办法:服务器B用HTTP库发一个POST请求到服务器A,服务器A处理后返回结果。

  • 听起来简单,但写起来麻烦------
  • 你得手动拼URL、序列化参数为JSON、处理HTTP状态码、反序列化响应、处理网络超时、如果服务器A挂了还得写重试逻辑......

这些和我们的业务逻辑完全无关,但我们必须写,不写就跑不起来。

这就是RPC要解决的问题

一、什么是RPC?

RPC 全称 Remote Procedure Call(远程过程调用)。

  • 它的核心目标就一句话:让你在A机器上,像调用本地函数一样调用B机器上的函数,不用关心网络传输、数据序列化这些底层细节。

我们对比一下

本地调用:

cpp 复制代码
int res = add(1, 2);   // add函数和调用方在同一个进程里,直接执行

RPC调用(理想情况):

cpp 复制代码
int res = remote_add(1, 2);  // remote_add的函数体运行在另一台服务器上

这一个函数里虽然看起来和本地函数用法一模一样,但是他的背后自动完成了网络传输、参数序列化、结果回传

RPC的本质,就是把"跨机器的网络通信"伪装成"同一进程内的函数调用"。

二、什么是JsonRpc?

RPC只是一种思想,它不是具体的代码

  • 要实现RPC,我们需要一套协议规范来规定请求和响应的格式。

JsonRpc就是其中一种轻量级的协议规范,它的特点:

  • 用JSON序列化数据:可读性强,跨语言支持好
  • 基于TCP或HTTP传输:简单通用
  • 无状态、轻量:没有XML-RPC那么重的格式,也没有gRPC那么多的依赖(protobuf、HTTP2等)

举个例子,一次JsonRpc调用的请求长这样:

json 复制代码
{
    "jsonrpc": "2.0",
    "method": "add",
    "params": [1, 2],
    "id": 1
}

服务端处理后返回:

json 复制代码
{
    "jsonrpc": "2.0",
    "result": 3,
    "id": 1
}

请求和响应都是纯JSON字符串,任何语言都能解析。 这就是JsonRpc跨语言能力的来源。

我们说的"C++远程调用组件库",就是基于JsonRpc协议,用C++封装完整的一组RPC通信能力的工具库。

三、RPC的工作原理


四、本地调用和远程调用的区别

我们看下面这张表,就明白了本地调用和远程调用的区别

维度 本地调用 RPC远程调用
执行位置 同一进程/同一台机器 不同进程/不同机器
通信方式 直接内存跳转、寄存器/栈传参 网络传输数据(TCP)
延迟 纳秒级,无网络开销 毫秒级,取决于网络环境
传参限制 支持指针、引用、复杂内存对象 不能传指针(远端内存地址无意义)
序列化 不需要(二进制兼容) 必须(参数转成JSON/二进制流)
异常处理 只需处理函数内部逻辑错误 还要处理网络断开、超时、远端进程崩溃

RPC的目标不是让远程调用和本地调用完全一样(物理上不可能),而是让开发者在写代码时不用关心网络层的存在。

五、一个完整的RPC框架需要什么?

  • 根据现代分布式系统的要求,一个功能完整的RPC框架需要具备以下能力:

第一层:通信基础

  • 序列化协议 (JSON / Protobuf / MessagePack)
  • 通信协议 (TCP / HTTP / HTTP2)
  • 连接复用 (长连接,避免频繁握手)

第二层:服务治理

  • 服务注册 (服务启动时向注册中心报到)
  • 服务发现 (客户端从注册中心找到服务地址)
  • 负载均衡 (多实例时选一个健康的节点)
  • 服务监控 (调用量、延迟、错误率统计)

第三层:调用模式

  • 同步调用 (发请求,阻塞等结果)
  • 异步调用 (发请求,结果回来时通知我)
  • 订阅/推送 (服务端主动向客户端推送消息)

六、技术选型

本项目的技术栈:

功能 选择的库 为什么选它
JSON序列化 JsonCpp C++领域最轻量的JSON库之一,语法直观
网络通信 muduo Reactor模式、非阻塞IO、高并发
构建工具 CMake 跨平台标准
语言 C++17 性能硬实力 + 支持现代特性

七、muduo库讲解

  • 这是本项目最重要的底层依赖

7.1 muduo是什么?

muduo是一个基于Reactor模式的C++网络库,由陈硕(chenshuo)开发。

它的设计哲学:one loop per thread(一个线程一个事件循环),每个I/O线程运行一个事件循环,监听并处理该线程负责的所有socket事件。

7.2 为什么RPC项目需要muduo?

RPC框架的核心是网络通信------客户端和服务端之间要发请求、收响应。

如果我们这块从头手写...

  • 创建socket、bind、listen、accept、connect......全是系统调用
  • 用epoll/poll管理成百上千个连接的事件
  • 处理TCP的粘包、半包问题
  • 设计线程模型,让多个连接并发处理
  • 写定时器处理超时逻辑

但每个项目都重新写一遍完全是浪费时间浪费精力

muduo帮我们把这些底层的脏活累活全干了。 我们只需要关注RPC协议本身:怎么组织请求和响应、怎么注册服务、怎么路由调用。

7.3 muduo和我们项目的关系

复制代码
我们的JsonRpc组件库
    │
    ├── 序列化层:JsonCpp(把C++对象 <--> JSON字符串)
    ├── 协议层:自己实现(JsonRpc 2.0 规范)
    └── 传输层:muduo(负责TCP建连、收发数据、事件循环)

muduo负责"怎么把数据从A机器传到B机器",我们的RPC层负责"传过去的数据是什么格式、代表什么含义"。

  • 这就是分层设计的优势:各层职责清晰,可以独立替换。假如以后想换成gRPC的HTTP2传输,只需要替换传输层,RPC协议层完全不动。

八、开发环境搭建

8.1 系统环境

本项目基于 Ubuntu 24.04 LTS 开发。

8.2 基础编译工具

bash 复制代码
sudo apt install -y \
g++ \
make \
cmake \
git \
gdb \
wget \
lrzsz
  • g++:C++11编译器
  • make/cmake:构建工具
  • git:版本管理
  • gdb:调试工具
  • wget:命令行下载文件
  • lrzsz:Linux文件传输工具(sz/rz命令)

8.3 安装项目依赖库

bash 复制代码
sudo apt install -y \
libjsoncpp-dev \
libboost-all-dev \
zlib1g-dev
  • jsoncpp:JSON序列化与反序列化
  • boost:muduo网络库的强制依赖
  • zlib:muduo编译时需要

8.4 编译安装muduo网络库

muduo没有apt安装包,需要从源码编译。注意:Ubuntu 24有几个兼容性问题,必须按下面的步骤来。

bash 复制代码
# 1. 克隆muduo源码
git clone https://github.com/chenshuo/muduo.git

# 2. 进入源码目录
cd muduo

# 3. Ubuntu 24 专属修复(跳过这步会编译报错!)
sed -i 's/std::unary_function/std::__unary_function/g' muduo/base/TimeZone.cc

# 4. 编译(只编译C++核心部分,不编译protobuf相关)
./build.sh -j4

# 5. 安装到系统目录
sudo ./build.sh install

安装完成后,muduo的头文件和库文件会分别安装到:

复制代码
/usr/local/include/muduo/       # 头文件
/usr/local/lib/libmuduo_*.a    # 静态库文件

CMake项目中使用时,只需在CMakeLists.txt里加上:

cmake 复制代码
find_package(muduo REQUIRED)
target_link_libraries(your_project muduo_net muduo_base)

以上就是本篇的内容,下一篇我们将详细讲解Muduo库及其知识点


我的个人主页,欢迎来阅读我的其他文章
https://blog.csdn.net/2402_83322742?spm=1011.2415.3001.5343

我的C++远程调用组件库RPC专栏
欢迎来阅读指出不足
https://blog.csdn.net/2402_83322742/category_13159666.html?spm=1001.2014.3001.5482

相关推荐
王老师青少年编程2 小时前
csp信奥赛C++高频考点专项训练之贪心算法 --【部分背包问题】:部分背包问题
c++·算法·贪心·csp·信奥赛·部分背包问题
handler012 小时前
【Linux 笔记】GDB 调试速查手册
linux·运维·c语言·c++·笔记
无忧.芙桃2 小时前
现代C++讲解之enum class,static_assert,tuple的使用
开发语言·c++
6Hzlia2 小时前
【Hot 100 刷题计划】 LeetCode 142. 环形链表 II | C++ 哈希表直觉解法
c++·leetcode·链表
周杰伦fans2 小时前
深入 C# 匿名类型:从 `new { Ask = ask }` 说起
开发语言·c#
fish_xk2 小时前
c++中的继承
开发语言·c++
froginwe112 小时前
CSS 图像透明/不透明
开发语言
初心未改HD2 小时前
Go语言Map底层原理与并发安全深度解析
开发语言·golang
Brilliantwxx2 小时前
【算法题】日期类算法题
开发语言·c++·笔记·程序人生·算法