当前位置: 首页 > article >正文

【C++项目】从零实现RPC框架「二」:项⽬设计

🌈 个人主页:Zfox_
🔥 系列专栏:C++从入门到精通

目录

  • 一:🚀 理解项⽬功能
  • 二:🔥 框架设计
    • 🦋 服务端模块划分
      • 🎀 `Network`
      • 🎀 `Protocol`
      • 🎀 `Dispatcher`
      • 🎀 `RpcRouter`
      • 🎀 `Publish-Subscribe`
      • 🎀 `Registry-Discovery`
      • 🎀 `Server`
    • 🦋 客⼾端模块划分
      • 🎀 `Network`
      • 🎀 `Protocol`
      • 🎀 `Dispatcher`
      • 🎀 `Requestor`
      • 🎀 `RpcCaller`
      • 🎀 `Publish-Subscribe`
      • 🎀 `Registry-Discovery`
      • 🎀 `Client`
    • 🦋 框架设计
      • 🎀 抽象层
      • 🎀 具象层
      • 🎀 业务层
      • 🎀 整体设计框架
  • 三:🔥 共勉

一:🚀 理解项⽬功能

🧑‍💻 本质上来讲,我们要实现的 rpc(远端调⽤)思想上并不复杂,甚⾄可以说是简单,其实就是客户端想要完成某个任务的处理,但是这个处理的过程并不⾃⼰来完成,⽽是,将请求发送到服务器上,让服务器来帮其完成处理过程,并返回结果,客户端拿到结果后返回。

在这里插入图片描述

💗 然⽽上图的模型中,是⼀种多对⼀或⼀对⼀的关系,⼀旦服务端掉线,则客户端⽆法进⾏远端调⽤,且其服务端的负载也会较⾼,因此在 rpc 实现中,我们不仅要实现其基本功能,还要再进⼀步,实现分布式架构的 rpc

🐳 分布式架构:简单理解就是由多个节点组成的⼀个系统,这些节点通常指的是服务器,将不同的业务或者同⼀个业务拆分分布在不同的节点上,通过协同⼯作解决⾼并发的问题,提⾼系统扩展性和可⽤性。

🦈 其实现思想也并不复杂,也就是在原来的模型基础上,增加⼀个注册中⼼,基于注册中⼼不同的服务提供服务器向注册中⼼进⾏服务注册,相当于告诉注册中⼼⾃⼰能够提供什么服务,⽽客户端在进⾏远端调⽤前,先通过注册中⼼进⾏服务发现,找到能够提供服务的服务器,然后发起调⽤。

在这里插入图片描述
⽽其次的发布订阅功能,则是依托于多个客户端围绕服务端进⾏消息的转发。

不过单纯的消息转发功能,并不能满⾜于⼤部分场景的需要,因此会在其基础上实现基于主题订阅的转发。

在这里插入图片描述

基于以上功能的合并,我们可以得到⼀个实现所有功能的结构图

在这里插入图片描述

在上图的结构中,我们甚⾄可以让每⼀个 Server 作为备⽤注册中⼼形成分布式架构,⼀旦⼀个注册中⼼下线,可以向备⽤中⼼进⾏注册以及请求,且在此基础上客户端在请求Rpc服务的时候,因为可以有多个 rpc-provider 可选,因此可以实现简单的负载均衡策略,且基于注册中⼼可以更简便实现发布订阅的功能。

项⽬的三个主要功能:

  • rpc调⽤
  • 服务的注册与发现以及服务的下线/上线通知
  • 消息的发布订阅

二:🔥 框架设计

🦋 服务端模块划分

服务端的功能需求:

  • 基于⽹络通信接收客⼾端的请求,提供 rpc 服务
  • 基于⽹络通信接收客⼾端的请求,提供服务注册与发现,上线 &下线通知
  • 基于⽹络通信接收客⼾端的请求,提供主题操作(创建/删除/订阅/取消),消息发布

在服务端的模块划分中,基于以上理解的功能,可以划分出这么⼏个模块

  1. Network:⽹络通信模块
  2. Protocol:应⽤层通信协议模块
  3. Dispatcher:消息分发处理模块
  4. RpcRouter:远端调⽤路由功能模块
  5. Publish-Subscribe:发布订阅功能模块
  6. Registry-Discovery:服务注册/发现/上线/下线功能模块
  7. Server:基于以上模块整合⽽出的服务端模块

🎀 Network

该模块为⽹络通信模块,实现底层的⽹络通信功能,这个模块本质上也是⼀个⽐较复杂庞⼤的模块,因此鉴于项⽬的庞⼤,该模块我们将使⽤陈硕⼤佬的 Muduo 库来进⾏搭建。

🎀 Protocol

⛰️ 应⽤层通信协议模块的存在意义:解析数据,解决通信中有可能存在的粘包问题,能够获取到⼀条完整的消息。

在前边的 muduo 库基本使⽤中,我们能够知道想要让⼀个 服务端/客⼾端 对消息处理,就要设置⼀个 onMessage 的回调函数,在这个函数中对收到的数据进⾏应⽤层协议处理。

Protocol模块就是是⽹络通信协议模块的设计,也就是在⽹络通信中,我们必须设计⼀个应⽤层的⽹络通信协议出来,以解决⽹络通信中可能存在的粘包问题,⽽解决粘包有三种⽅式:特殊字符间隔,定⻓,LV格式。

⽽我们项⽬中将使⽤LV格式来定义应⽤层的通信协议格式
在这里插入图片描述
Length:该字段固定4字节⻓度,⽤于表⽰后续的本条消息数据⻓度。

MType:该字段为Value中的固定字段,固定4字节⻓度,⽤于表⽰该条消息的类型。

  • Rpc调⽤请求/响应类型消息
  • 发布/订阅/取消订阅/消息推送类型消息
  • 主题创建/删除类型消息
  • 服务注册/发现/上线/下线类型消息

IDLength:为消息中的固定字段,该字段固定4字节⻓度,⽤于描述后续ID字段的实际⻓度。

MID:在每条消息中都会有⼀个固定字段为ID字段,⽤于唯⼀标识消息,ID字段⻓度不固定。

Body:消息主题正⽂数据字段,为请求或响应的实际内容字段。

🎀 Dispatcher

🍺 模块存在的意义:区分消息类型,根据不同的类型,调⽤不同的业务处理函数进⾏消息处理。

muduo 库底层通信收到数据后,在 onMessage 回调函数中对数据进⾏应⽤层协议解析,得到⼀条实际消息载荷后,我们就该决定这条消息代表这客⼾端的什么请求,以及应该如何处理。

因此,我们设计出了Dispatcher模块,作为⼀个分发模块,这个模块内部会保存有⼀个 hash_map<消息类型, 回调函数>,以此由使⽤者来决定哪条消息⽤哪个业务函数进⾏处理,当收到消息后,在该模块找到其对应的处理回调函数进⾏调⽤即可。

在这里插入图片描述
消息类型:

  • rpc请求&响应
  • 服务注册/发现/上线/下线请求&响应
  • 主题创建/删除/订阅/取消订阅请求&响应,消息发布的请求&响应


http://www.kler.cn/a/585340.html

相关文章:

  • 【React】useState及底层处理机制
  • 一篇博客搞定时间复杂度
  • Pytorch的入门
  • Java 8 + Tomcat 9.0.102 的稳定环境搭建方案,适用于生产环境
  • 使用curl随机间隔访问URL-使用curl每秒访问一次URL-nginx
  • Vue配置和安装教程(2025最新)
  • CGI程序处理每一帧VDEC视频数据并输出到HTML页面
  • 【Unity】TextMesh Pro显示中文部分字体异常
  • Cascadeur-3D关键帧动画软件
  • Redis--zset类型
  • 信号处理抽取多项滤波的数学推导与仿真
  • 警惕!Ollama大模型工具的安全风险及应对策略
  • Webpack 和 Vite 的主要区别
  • C# net deepseek RAG AI开发 全流程 介绍
  • flinkOracleCdc源码介绍
  • Python 与 sklearn 库:轻松构建 KNN 算法双版本
  • 如何撰写一份清晰专业的软件功能测试报告
  • Vue项目搜索引擎优化(SEO)终极指南:从原理到实战
  • JVM 垃圾回收器的选择
  • 海量数据查询加速:Presto、Trino、Apache Arrow