分布式C++ Actor框架 - 架构核心
1. 设计目标
- 解耦: 实现业务逻辑与底层网络、并发模型的完全分离。
- 性能: 提供高吞吐、低延迟的通信能力,并给予用户对线程模型的完全控制。
- 健壮性: 通过自动化机制处理节点发现、故障检测和网络错误。
- 可扩展性: 架构支持节点数量的水平扩展和未来功能的纵向扩展。
2. 核心架构
-
分层模型: 系统采用严格分层设计。
- Socket抽象层 (
lean_socket
): 最底层,提供一个对Asio完全封装的、接口驱动的异步网络API。 - Actor网络传输层 (
ActorNetworkTransport
): 基于lean_socket
,负责节点间的连接管理和Actor消息的可靠传输。 - Actor核心: 提供单进程内的Actor生命周期管理、调度和消息邮箱机制。
- 分布式服务: 实现节点发现、集群管理等跨节点功能。
- Socket抽象层 (
-
线程模型:
- 采用用户驱动的线程池模型。框架库本身不创建任何线程。
- 用户需创建
lean_socket::IoContext
实例,并自主决定启动多少个线程来调用IoContext::run()
。 - 优势: 应用层对并发性能有绝对控制权,且允许多个网络服务(如后端节点通信、前端网关)共享同一个高效的线程池,避免资源浪费。
-
节点拓扑:
- 采用中心化的注册与发现,去中心化的业务通信模型。
- 注册中心节点 (Registry Node): 单一入口点,维护集群成员的动态列表。解决节点发现问题。
- 工作节点 (Worker Node): 执行业务逻辑。启动时向注册中心注册,获取对等节点列表,并建立全连接(Full-Mesh)的对等网络。节点间的业务消息直接通过P2P连接发送,不经过注册中心。
3. 关键模块与协议
-
lean_socket
抽象层:- 目的: 建立编译防火墙,使用户代码完全不依赖Asio。这能极大提升编译速度,并为未来更换网络后端提供可能。
- 技术: 采用Pimpl Idiom,将所有Asio相关的定义和实现细节隐藏在
.cpp
文件中。 - 接口哲学: 对外提供高级的Proactor风格API(如
async_read
完成后直接返回数据),对用户屏蔽底层IO模型的复杂性。
-
ActorNetworkTransport
传输层:- 核心职责: 作为
lean_socket
和Actor核心之间的适配器。 - 消息成帧 (Message Framing): 必须在TCP字节流之上实现消息边界。采用长度前缀协议:每条序列化后的Actor消息前,附加一个4字节(或8字节)的网络字节序整数,用于表示消息体的精确长度。这是保证在流式传输中可靠地重组消息的关键。
- 核心职责: 作为
-
节点发现协议:
- 机制: 基于长连接和周期性心跳的健康检查。
- 流程:
- 注册: 工作节点连接注册中心,发送自身监听地址。
- 发现: 注册中心返回当前所有在线节点的地址列表。
- 连接: 工作节点根据列表与其他对等节点建立连接。
- 广播: 注册中心向所有老节点广播新节点的加入信息。
- 心跳: 工作节点定期向注册中心发送心跳包以维持注册状态。
- 故障通告: 注册中心在心跳超时后,向全网广播节点离线消息。
-
Actor ID 结构:
- 设计: 采用64位整数作为全局唯一ID。高16位为
NodeId
,低48位为节点内自增的LocalActorId
。 - 优势: 实现无状态、高效的路由。从
ActorId
中可直接通过位运算提取出目标NodeId
,无需任何查表操作即可确定消息是否需要跨节点转发。
- 设计: 采用64位整数作为全局唯一ID。高16位为