C++ Json-Rpc框架 项目逻辑设计

Server


• RpcServer:rpc功能模块与⽹络通信部分结合

RpcServer分为两部分 1.提供函数调用服务的服务端 2.提供服务注册的客户端

对内提供好rpc服务的路由关系管理map<method,服务描述对象>,以及rpc请求消息的分发处理函数。给Dispatcher提供onRpcRequest rpc请求的回调函数,根据请求中的method(),从map中找到对应的服务描述对象 进行参数检查,无误调用函数处理 最后向服务端返回应答。

右侧serviceRegister(method, service) 是服务端本地注册接口,用于将某个 method(方法名)与其对应的 service(服务描述对象)进行绑定,注册到本地的 RpcRouter 中,便于后续接收到 RPC 请求时进行路由调用对应的函数服务。

但仅仅本地知道能提供哪些服务还不够,如果希望其他客户端也能发现这些服务并远程调用,就必须通过 RegistryClient注册客户端 将服务信息(method 与 host 地址)注册到服务注册中心 RegistryServer。

• RegistryServer:服务发现注册功能模块与⽹络通信部分结合

对内提供好服务提供者和服务发现者的数据管理 。给Dispatcher提供服务操作请求的分发处理函数onServiceRequest,分为服务发现/服务注册。

服务发现:返回能提供该method函数的主机地址列表

服务注册:将提供者信息管理起来

PDManager分为服务提供者管理,服务发现者管理。1.进行服务注册  提供者管理要add新增提供者 发现者管理要给订阅该method方法的发现者进行服务上线通知ontifyOffline。2.进行服务发现 发现者管理add新增发现者 并返回method方法提供者列表(提供者管理)应答。 

onShutdown服务提供者或者发现者断开连接时的回调函数,1.提供者断开连接 发现者管理发送服务下线通知ontifyOffline  提供者管理del删除该提供者的管理  2.发现者断开 不需要通知 发现者管理del删除该发现者的管理


• TopicServer:发布订阅功能模块与⽹络通信部分结合

对内完成主题map<key,topic>和订阅者信息map<conn,subscriber>的管理。topic包含主题名称+当前主题的订阅者列表vector<sub>,sub包含订阅者conn+订阅的主题列表名称vector<string>.

给Dispatcher回调函数onTopicRequest处理主题操作的请求,1.主题创建2.主题删除3.订阅主题4.取消订阅5.向主题发布消息

双向映射管理:一方面维护“主题 → 订阅者”,另一方面维护“订阅者 → 主题”

1.订阅主题 订阅者sub中新增主题 被订阅的主题topic对象中订阅者列表也要新增订阅者

2.取消订阅 同理订阅者删除了主题 主题对象中也要删除订阅者

3.删除主题 map<key,topic>删除映射,订阅该主题的订阅者中也要删除该主题

4.连接断开的回调函数onShutdown 处理订阅者断开连接, map<conn,sub>删除映射 订阅者订阅的所以主题中删除该订阅者

服务端总体逻辑

服务端总体有3个回调函数注册到Dispatcher中,onRpcRequest 处理rpc请求的 onServiceRequest处理服务请求 onTopicRequest处理主题操作请求的

Client

将以上模块进⾏整合就可以实现各个功能的客⼾端了。


• RegistryClient:服务注册功能模块与⽹络通信客⼾端结合


服务注册客户端 提供一个服务注册的接口registryMethod 通过requestor进行发送服务注册请求并等待应答。

给Dis注册的回调函数onResponse是Requestor模块的接收应答的回调函数,毕竟请求由Requestor发送 也由它设置回调函数接收并处理。

• DiscoveryClient:服务发现功能模块与⽹络通信客⼾端结合

服务发现客户端 对内提供处理服务端主动推送的服务上线/下线通知请求的分发接口,对外提供服务发现接口,设置服务下线的处理回调(当作成员函数 构造时传入 删除连接池中的该服务的长连接)

所以给Dispatcher的回调函数有两个,1onResponse客户端主动发送服务发现请求的应答回调 2.onServiceRequest处理服务端主动推送的服务上线/下线通知请求的回调(服务下线时调用_offline_callback删除长连接)。


• RpcClient:DiscoveryClient & RPC功能模块与⽹络通信客⼾端结合

这个RpcClient也是分为两部分 1.提供rpc调用的客户端 2.提供服务发现的服务发现客户端

对外提供3个call函数,1.同步2.异步future3.异步回调,但内部是套用Requestor的3个send函数进行调用的。其中同步call是调用的同步send(内部套用异步send+外部等待) 23异步future和异步回调call都是调用的回调send,2异步future是在回调函数中设置的set_value(bind捕获为了延长promise的生命周期)

call进行rpc调用前我们必须要找到能提供服务的服务端地址,怎么知道?向注册中心进行服务发现,这就需要服务端发现客户端 进行服务发现。向外提供1.服务发现接口2.服务上线/下线的回调函数                   


• TopicClient:发布订阅功能模块与⽹络通信客⼾端结合

发布订阅客户端,对内提供主题消息推送的消息分发处理回调函数onpublish(根据本地map<key,cb>调用对应主题的回调函数 订阅主题时候传入的),对外提供主题操作的函数1.主题创建2.主题删除3.订阅主题4.取消订阅5.主题消息发布

这里给Dispathcer传入的回调函数也是两个,1.onResponse客户端主动发送服务发现请求的应答回调 2.onPublish 服务端主动发送的主题消息 进行分发调用对应的回调函数。

客户端总体逻辑图

dispatcher中存入有三个回调函数,1.客户端主动requestor()发送请求,自然由它的回调函数onResponse进行处理 2.服务端主动发送的消息 主题消息的发布,对订阅该主题的客户端发送消息,对于被动接收到的主题消息 topic客户端自己设置回调函数onPublish给dispatcher模块。3.服务端主动发送的消息 服务上线/下线通知 registry客户端设置回调函数onServiceRequest给disoatcher模块

服务端抽象层

主 Reactor 负责监听 listenfd 上的新连接请求,一旦有连接到来就通过 accept() 建立连接,获取客户端的套接字 connfd。(并封装为 BaseConnection 对象)

从 Reactor 则负责监听所有客户端套接字的 IO 事件(如可读)。当客户端发来数据,服务端就通过对应的 connfd 从内核读取数据,先写入 BaseBuffer 输入缓冲区。

然后上层 Protocol 模块从缓冲区中读取数据,处理粘包拆包,将原始字节数据反序列化为 BaseMessage 对象,最终由 Dispatcher 根据 msg->type() 派发到注册的业务处理回调函数中去。

客户端连接建立时 会调用服务端外部提供的2个set接口,onClose onConn,而onMessage回调是Dispatcher设置的 onMessage把messgae传给Dis让它按消息类型派发数据

(Dispatcher 里的回调函数是由各个业务模块在初始化阶段,通过 registerHandler(msgType, 回调函数) 主动注册进去的)

客户端抽象层

客户端的 Reactor 维护了一条与服务端的连接,监听这个套接字 获取服务端返回的应答和主题服务上下线推送/主题消息发布广播,并通过 Dispatcher 根据消息类型调用对应的回调函数。

给外部提供了5个接口,1.connect()建立客户端到服务端的 TCP 连接 2.shutdown()主动关闭当前连接 3.setCloseCallback()关闭连接回调函数 4.setConnectionCallback()连接建立成功回调函数 5.send()发送请求

oMessage也是由dis提供 对应类型的回调函数由各模块初始化时传入

具象层

针对不同的请求,从BaseMessage中派⽣出不同的请求和响应类型,以便于在针对指定消息处理时,能够更加轻松的获取或设置请求及响应中的各项数据元素。

BaseMessage最基础的消息结构体:消息id 消息类型mtype(epc topic service)

JsonMessage继承BaseMessage:新增body字段 存储请求/响应的内容

JsonMessage子类可以分为 请求和响应,因为如果是响应类的话 需要有响应码 check()检查响应是否正确。

1.JsonRequest 请求消息的基类 无新增字段

        1.RpcRequset 新增 1.method调用的函数名 2.parameters 参数(json格式 参数名:类型)

        2.TopicRequset 1.key主题名 2.optype主题操作类型(创建/删除/订阅/取消订阅/主题发布) 3.(msg)如果是主题发布 就有这个字段 主题发布的内容

        3.ServiceRequset 1.method函数名 2.optype服务操作类型(注册/发现/上线/下线)

3.host 告诉服务端自己的地址 (仅在注册、上线时需要)

2.JsonResponse 应答消息的基类 重写chekc() 如子类需要根据自己结构判断可再进行重写

        1.RpcResponse 1.rcode返回码 2.result 结果数据

        2.TopicResponse 1.rcode返回码 主题的操作应答只需要返回是否完成就可以

        3.ServiceResponse 

                注册/上线/下线操作:1.rcode返回码 2.optype服务操作类型

                发现操作:1.rcode 2.optype 3.method要发现的函数 4.hosts能提供method方法的主机地址列表

业务层

业务层就是基于底层的通信框架,针对项⽬中具体的业务功能的实现了,⽐如Rpc请求的处理,发布订阅请求的处理以及服务注册与发现的处理等等。

1.rpc请求处理

1.Client模块:对外提供call()接口,给用户进行rpc调用。内部通过Requestor发送rpc请求。

Requestor提供onResponse给Dispatcher模块 处理Requestor发送请求返回的应答。

2.中间传输层模块:通过底层网络通信NetWork发送数据,Dispatcher模块根据消息类型的不同调用对应的回调函数处理。

3.Server模块:对内完成method->函数的映射管理,并提供onRpcRequest给Dispatcher模块 处理rpc请求消息的回调函数,调用对应的rpc函数 并返回应答。

2.发布订阅请求的处理

1.Client模块:PSManager对外提供5个接口,这些请求都是通过Requestor()进行发送,因此Requestor要给Dis提供onResponse回调处理 这些请求对应的响应。除此之外,PSManager还要给Dis提供onPublish函数,处理主题消息,因为这是服务端主动发送的 并不是Requestor发送请求返回的响应,所以单独处理。

2.Network 负责客户端与服务端之间的底层连接及消息收发  Dispatcher消息派发

3.Server模块:PSManger给Dis提供onTopicRequest 处理topic主题消息调用对应函数完成主题创建/删除/... 并发送操作是否完成的应答。  如果是主题发布,服务端还需要主动给订阅该主题的客户端进行广播,通过Publish函数send发送消息。

3.服务注册&发现

1.Client模块:PDManager模块分为两部份 1.Provider服务提供者 对外提供服务注册serviceRegistry() 通过Requestor发送服务注册请求。2.Discoverer服务发现者 对外提供服务发现serviceDiscovery() 也是通过Requestor发送服务发现请求。除此之外,还要给Dis提供onServiceRequest来处理服务端主动发送的 服务上线/下线消息的回调处理函数。

2.

3.Server模块:PDManager给Dis提供一个统一的接口onServiceRequest来处理客户端发来的服务注册/服务发现请求,1.服务注册 Pro新增提供者 Discover进行服务上线通知 返回注册成功应答        2.服务发现 Discover新增发现者 返回发现成功应答包含服务提供者地址

因此服务发现者 需要有服务上线/下线通知的函数 onlineNotify/offlineNotify,服务端给客户端主动发送消息。

整体设计框架

整个项目的实现分为三层,抽象层 具象层 业务层。

抽象层 将底层的网络通信机制(BaseServer BaseClient Basebuffer BaseConnection都是封装的Muduo库) 应用层通信协议(自己实现的LVProtocol) 请求响应的数据结构进行统一的封装抽象(BaseMessgae 派生出对应的子类),还有个回调函数MessageCallback 将原始字节流转化为message对象时触发 给Dispatcher进行派发。

具象层 底层网络通信借助Muduo库  通信协议自己实现的LV通信协议  请求响应的数据结构根据三个模块派生对应的子类

业务层 三个模块各自提供处理对应请求的回调函数给Dispatcher模块。

Dispatcher模块MType对应的回调函数

请求类都是由对应的服务端提供回调函数1.rpc服务端 onRpcRequest 2.服务注册/发现服务端onServiceRequest 3.主题服务端onTopicRequest

响应类由Requestor提供的onResponse处理

主题消息发布topic客户端提供的publish 服务上下线通知服务客户端的onServiceRequest

功能场景消息类型(MType)说明
RPC 请求MType::REQ_RPC客户端发起 RPC 函数调用请求
RPC 响应MType::RSP_RPC服务端返回 RPC 执行结果
Topic 请求MType::REQ_TOPIC客户端执行主题相关操作(订阅、发布等)
Topic 响应MType::RSP_TOPIC服务端返回主题请求处理结果
服务请求MType::REQ_SERVICE客户端请求服务注册/发现/上下线等操作
服务响应MType::RSP_SERVICE服务端对服务请求的响应

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/pingmian/84977.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Agent开发相关工具

LangChain LangChain LangGraph LangGraph LangSmith GraphRAG RAGFlow what-is-graphrag Dify n8n vLLM Model Context Protocol AutoGen CodeMirror Milvus Chroma

进程管理(一)

一. 进程的基本信息 1.1 进程的概念、组成及信息 1.1.1 概念 进程的概念与程序相对&#xff0c;程序是静态的而进程是动态的&#xff0c;一个程序执行多次会有多个不同的进程 1.1.2 组成 PCB&#xff08;程序控制块&#xff09;&#xff1a; 是一种保存下列信息的数据结构&…

k8s 中 cpu 核数的理解

物理核还是逻辑核 在 Kubernetes&#xff08;k8s&#xff09;编排文件&#xff08;如 Pod 或 Deployment 的 YAML 文件&#xff09;中设置的 CPU 核数&#xff0c;针对的是逻辑核数&#xff08;Logical Cores&#xff09;&#xff0c;而非物理核数&#xff08;Physical Cores&…

arcpy数据分析自动化(2)

数据处理 在提取数据后&#xff0c;我们需要对字段进行标准化处理&#xff0c;例如统一土地利用类型的命名。 # 定义字段映射字典 field_mapping {"Residential": "居住用地","Commercial": "商业用地","Industrial": &q…

在VMware虚拟机集群中,完成Hive的安装部署

Hive是分布式运行的框架还是单机运行的&#xff1f; Hive是单机工具&#xff0c;只需要部署在一台服务器即可。 Hive虽然是单机的&#xff0c;但是它可以提交分布式运行的MapReduce程序运行。 我们知道Hive是单机工具后&#xff0c;就需要准备一台服务器供Hive使用即可。 同…

Linux运维新人自用笔记(部署 ​​LAMP:Linux + Apache + MySQL + PHP、部署discuz论坛)

内容全为个人理解和自查资料梳理&#xff0c;欢迎各位大神指点&#xff01; 每天学习较为零散。 day19 简单搭建网站 下载apache服务 #下载阿帕奇服务 [rootxun ~]# yum install httpd -y#关闭防火墙 [rootxun ~]# iptables -F#启动服务 [rootxun ~]# systemctl start http…

Kubernetes架构解析

Kubernetes 技术栈的深度解析&#xff0c;涵盖架构设计、核心组件、生态工具及二次开发实践&#xff0c;结合实战案例说明其内在关联&#xff1a; 一、Kubernetes 架构设计 核心分层模型 #mermaid-svg-CnFwJbuzaABZpTBr {font-family:"trebuchet ms",verdana,arial…

langchain4j整合springboot

langchain4j整合springboot 1.搭建项目架子配置文件Controller测试测试结果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/35b8bd04f3034bd990861f065bc73d2f.png) 1.搭建项目架子 配置文件 参考官网配置引入 <?xml version"1.0" encoding"UTF…

408第一季 - 数据结构 - 平衡二叉树

平衡二叉树 定义 缩写记一下 AVL 还有下面这些&#xff0c;can you try&#xff1f; 平衡二叉树的插入 LL平衡旋转&#xff08;右单旋转&#xff09; 怎么理解&#xff1f; 首先我们可以看见啊&#xff0c;b图A左边和右边的不平衡的&#xff0c;非常的难受 于是我们可以这…

VR 地震安全演练:“透视” 地震,筑牢企业安全新护盾​

与传统的地震安全教育方式相比&#xff0c;VR 地震安全技术具有无可比拟的优势。在过去漫长的岁月里&#xff0c;我们主要依赖书本、讲座和视频等较为常规的手段来了解地震知识和逃生技巧。​ 书本上密密麻麻的文字以及静态的图片&#xff0c;虽然能够较为系统地传递理论性的信…

30-Oracle 23ai-回顾从前的Flashback设置

配置和测试了Oracle 23 ai的Flashback Log Placement后&#xff0c; 刚好身边11g,19c的环境都在&#xff0c;还是把从前的flashback整理下&#xff0c;温故知新&#xff0c;循序渐进。 一、闪回技术 Flashback Database 允许将整个数据库回退到过去的某个时间点/SCN&#xff…

Gartner《Reference Architecture for Federated Analytics》学习心得

研究背景 随着分析平台越来越易于被广泛用户使用,以及组织内用例的不断增多和多样化,分析架构的去中心化给专注于架构的分析专家带来了混乱。组织在交付一致、可复用和可信的分析方面面临挑战,分布式分析架构需要在控制和敏捷之间取得平衡,然而许多组织在这方面的控制力不…

Windows下Docker一键部署Dify教程

Windows环境下Docker部署Dify完整指南 &#x1f4cb; 目录 系统要求Docker安装验证Docker安装Dify部署访问Dify常见问题管理命令 &#x1f5a5;️ 系统要求 在开始安装之前&#xff0c;请确保你的Windows系统满足以下要求&#xff1a; 硬件要求 CPU: > 2核心内存: >…

idea maven打包很慢,怎么提速-多线程

作为一个技术运维人员&#xff0c;经常要更新程序然后重新打包发布jar包。由于程序子模块多&#xff0c;需要相互引用每次打包的时候都需要很久&#xff0c;怎么可以让打包快一点呢&#xff1f;可以启动打包的多线程。请参照下图设置&#xff0c;线程数量应该和cpu内核数量要能…

Java/Kotlin selenium 无头浏览器 [Headless Chrome] 实现长截图 三种方式

在自动化测试和网页抓取中&#xff0c;完整捕获整个页面内容是常见需求。传统截图只能捕获当前视窗内容&#xff0c;无法获取超出可视区域的页面部分。长截图技术通过截取整个滚动页面解决了这个问题&#xff0c;特别适用于&#xff1a; 保存完整网页存档生成页面可视化报告验…

【AI大模型】Elasticsearch9 + 通义大模型实现语义检索操作详解

目录 一、前言 二、Elasticsearch9 语义检索介绍 2.1 ES9 语义检索核心特性 2.2 semantic_text 字段类型说明 2.3 ES9 语义检索原理 2.4 ES9 语义检索优势与使用场景 三、 Elasticsearch9 搭建过程 3.1 环境说明 3.2 部署方式一 3.2.1 创建docker网络 3.2.2 获取es9镜…

linux开机原理以及如何开关机-linux023

linux开机原理以及如何开关机 Linux 系统启动过程概述 阶段描述内核引导启动时&#xff0c;BIOS执行自检&#xff0c;启动设备通常是硬盘。操作系统接管硬件后&#xff0c;读取/boot目录下的内核文件。运行 initinit是系统所有进程的起点&#xff0c;负责启动其他进程。它读取…

使用 socat 和 xinetd 将程序绑定到端口运行

在现代网络应用开发和系统管理中&#xff0c;经常需要将某些程序或脚本绑定到特定的网络端口上&#xff0c;以实现远程访问或服务化。例如&#xff0c;一个简单的 Python 脚本可能需要通过 TCP 端口提供服务&#xff0c;或者一个命令行工具需要通过网络接口暴露其功能。为了实现…

电阻篇---上拉电阻

一、上拉电阻的定义与本质 定义&#xff1a;上拉电阻是一端连接到电源&#xff08;VCC&#xff09;&#xff0c;另一端连接到电路节点的电阻元件&#xff0c;其核心作用是将该节点的电平 “拉” 至电源电压&#xff0c;使其在无信号输入时保持稳定的高电平状态。 本质原理&…