MsgTrans 2.0 Beta 1:把“高性能传输”升级为“可证明高性能可靠”

MsgTrans 2.0 Beta 1:把“高性能传输”升级为“可证明高性能可靠”

MsgTrans 是多协议高性能网络库,现在 MsgTrans 2.0 Beta 1 已经发布。 这是一次面向生产级实时网络的系统性重构,而不是在 1.x 上继续堆叠功能。 MsgTrans 继续通过统一 API 支持 TCP、WebSocket 和 QUIC,但 2.0 重新设计了事件传递、请求生命周期、写入确认、连接代际、资源限制、优雅关闭、协议扩展和公共 API。 我们的目标非常明确: 网络库不应只在正常环境里工作,还必须在弱网、拥塞、重连、超时、慢消费者和异常关闭下给出确定、可验证的结果。 一套业务代码,覆盖三种网络环境 MsgTrans 2.0 让业务层不再绑定具体协议。同一套消息、请求响应和会话处理逻辑,可以部署在三种传输之上。 | 协议 | 推荐场景 | 核心价值 | |---|---|---| | QUIC | 移动网络、弱网、高延迟、丢包环境 | 更适合互联网与低延迟传输 | | TCP | 稳定内网、服务间通信、长连接网关 | 成熟、稳定、行为可预测 | | WebSocket | 浏览器、HTTP 代理、防火墙限制、只放行普通 Web 流量的环境 | HTTP 基础设施兼容性更强 | | 自定义协议 | 专用硬件、私有链路、定制传输 | 通过 msgtrans::spi 接入统一传输层 | 业务无需为不同协议维护三套请求状态机、会话生命周期和错误处理逻辑。 2.0 的核心变化:可靠性成为架构属性 1. 有界事件主干,不再静默丢消息 MsgTrans 2.0 删除了核心数据路径中的广播事件总线,改为每连接独立的有界事件管道和 Session Actor: Connection → bounded channel → SessionActor → SessionHandler 慢消费者只会对自己的连接形成背压,不再影响其他连接。 数据、诊断和控制事件被拆分为不同平面: 数据事件:有界、背压、不得丢弃 诊断事件:允许在压力下丢弃,绝不挤占业务数据 关闭事件:不排在数据队列后面,保证连接能够及时退出 旧广播主干在内部饱和测试中曾复现约 91% 的消息丢失。2.0 直接移除了这条结构性风险。 2. 请求生命周期只有一个真相源 2.0 使用统一的 Request Registry 管理请求状态: Pending → Responding → Responded → SendFailed → TimedOut → SessionClosed → Dropped 状态迁移使用原子操作,保证: 一个请求最多只有一个响应者成功 重复响应不会产生第二个网络包 超时、断线和发送失败具有不同语义 会话关闭时立即清理关联请求 取消调用方 Future 不会留下永久 Pending 或 Responding 迟到响应不会完成另一条新请求 Responder 携带不可伪造的 RequestToken,业务方无法手动构造消息 ID 或绕过请求注册表。 3. 彻底关闭重连 ABA 与旧连接污染 每次连接都会获得独立、单调递增的 Session ID。 连接和代际信息存储在同一个原子生命周期槽中。旧连接迟到的 Response、ConnectionClosed 或异步发送,只能影响旧代会话,无法触碰重连后的新连接。 请求 ID 由传输层按会话分配,并且拒绝回绕。宁可明确返回资源耗尽,也不会复用仍可能存在迟到响应的 ID 空间。 4. Ok 终于代表真实成功 2.0 不再把“进入发送队列”包装成“发送成功”。 所有正式 send 路径都是 write-confirmed: let receipt = client.send(b"hello").await?; 只有底层写循环确认字节已经写入传输层,调用才返回成功。 如果只需要排队、不等待写入,可以显式使用: client.send_detached(b"hello").await?; 两种语义通过命名直接区分,不再出现真假难辨的 Ok(())。 请求超时现在返回真正的 Err,不再伪装成“成功但没有数据”。广播则返回 BroadcastReport,明确报告成功数量和每个会话的失败原因。 5. 可等待、可证明的确定性关闭 shutdown() 不再只是设置一个停止标记。 2.0 使用受控任务所有权和生命周期监督器,等待: listener 停止 scanner 退出 actor 与事件泵结束 会话资源释放 连接许可全部归还 监听端口真正释放 关闭结果通过 ShutdownReport 返回: let report = server.shutdown().await?; assert!(report.infra_stopped); assert!(report.permits_restored); assert!(report.clean); 这解决了 Ctrl+C 后 QUIC 或其他监听端口长时间不能重新绑定、幽灵会话占用连接配额、后台任务脱离服务器生命周期等问题。 严格、安全、统一的协议边界 Strict 成为默认策略 FramePolicy::Strict 现在是默认值。 以下输入都会被视为协议错误并关闭连接: 未知 Packet Type 未知 Compression Type WebSocket 文本帧 尾随多余字节 非法固定头 超过限制的扩展头或 Payload 无法解压的数据 声明长度与实际帧不一致 需要兼容 1.x 宽松行为时,仍可显式选择 FramePolicy::Lenient。 三协议共享同一套尺寸限制 TCP、WebSocket、QUIC 不再各自维护不同的隐藏上限。 ServerLimits 和 ClientLimits 统一控制: 最大 Payload 最大扩展头 最大帧尺寸 写入截止时间 事件管道容量 出站队列容量 Actor 邮箱容量 同一个包不会再出现“WebSocket 可以发,TCP 却突然断开”的协议差异。 压缩不再可能制造损坏帧 压缩通过 SendOptions 和 RequestOptions 指定,由传输层在 Payload 完成后统一处理: let options = SendOptions::new() .biz_type(7) .compression(CompressionType::Zstd); 如果构建时没有启用对应 codec,发送会明确失败,而不是把原始数据挂上“已压缩”标志继续发出。 入站解压只在共享事件边界执行一次。TCP、WebSocket、QUIC、客户端、服务端和自定义协议的上层消费者看到的始终是明文 Payload 与自洽的包头。 性能优化不是用可靠性换吞吐 MsgTrans 2.0 的性能方向不是盲目追求微基准数字,而是在稳定语义下减少热路径成本: Bytes 驱动的 Payload 与零拷贝切片解码 编码路径消除重复 Vec 和 freeze 拷贝 QUIC 读取缓冲减少无意义清零 每连接独立 Actor,降低跨连接共享竞争 ConnectionWriter 将写路径从连接状态锁中分离 等待队列和写入回执时不持有连接锁 压缩和解压只执行一次 广播选项在扇出前只准备一次 有界队列防止慢连接无限吞噬内存 TCP、WebSocket、QUIC Cargo feature 真正裁剪协议依赖 当前三协议压力测试均保持零传输错误,架构重构前后未观察到显著吞吐回退。 更小、更诚实的公共 API 2.0 删除了大量“看起来能用、实际上未接线”或暴露内部实现的接口。 公共面现在只有两部分: msgtrans::*:应用开发 API msgtrans::spi::*:协议扩展 API 内部 Transport、Request Registry、Session Actor、协议适配器和状态机不再泄漏到公共命名空间。 公共 API 由快照纳入 CI。一旦接口发生变化,构建会直接失败,避免文档和实现静默漂移。 1.x 用户必须关注的升级点 MsgTrans 2.0 保持 wire format 不变,规范的 1.x 与 2.0 节点可以互通。但 Rust 公共 API 是有意进行的 breaking change。 SessionHandler 拆分 单向消息和请求不再混在同一个入口: async fn on_message( &self, session_id: SessionId, packet: Packet, sender: SessionSender, ); async fn on_request( &self, session_id: SessionId, packet: Packet, responder: Responder, ); 请求只能通过消费式 Responder 回应。 Packet 字段私有化 packet.message_id(); packet.biz_type(); packet.payload(); packet.into_payload(); packet.try_encode()?; 编码成为可失败操作,超限数据不会再被静默截断。 发送参数拆分 let send = SendOptions::new() .biz_type(7) .compression(CompressionType::Zstd); let request = RequestOptions::new() .biz_type(7) .timeout(Duration::from_millis(500)); Raw Packet 发送入口已经删除,调用方无法再伪造 Request 类型和消息 ID。 WebSocket TLS 类型化 旧的 verify_tls: bool 被替换为: ClientTls::SystemRoots ClientTls::CustomCa(pem) ClientTls::Insecure 每个选项都有真实实现,Insecure 只适合开发环境。 深层 import 迁移 应用类型统一从 crate root 导入: use msgtrans::{Packet, ClientEvent, Responder}; 协议实现者使用: use msgtrans::spi::{Connection, ConnectionWriter, EventSink}; 完整迁移说明: 1.x → 2.0 迁移指南 2.0 架构说明 适用场景 MsgTrans 2.0 尤其适合: 即时通信、消息推送和实时协作 移动网络与弱网传输 游戏长连接和状态同步 内网微服务通信 IoT 设备与网关 同时面向 App、浏览器和后端服务的多协议网关 需要请求响应、单向消息、广播与断线重连的实时系统 需要自定义传输协议,但希望复用会话和请求生命周期的基础设施 如果项目只是普通 REST API,或者只需要短连接 HTTP 请求,MsgTrans 并不是 HTTP 框架的替代品。它面向的是持续连接、双向实时传输和可控生命周期。 如何开始 Beta 1 发布后可使用: [dependencies] msgtrans = { version = "2.0.0-beta.1", features = ["tcp", "websocket", "quic"] } 启用压缩: msgtrans = { version = "2.0.0-beta.1", features = ["tcp", "websocket", "quic", "zstd"] } 对于现有 1.x 项目,建议采用滚动升级: 先迁移公共 API并保持原协议部署。 在测试环境启用 Strict 策略。 验证超时、重连、慢消费者与服务关闭场景。 对移动网络优先试运行 QUIC。 生产环境先灰度单协议,再扩展到多协议入口。 结语 MsgTrans 1.x 证明了统一 TCP、WebSocket 和 QUIC 是可行的。 MsgTrans 2.0 要证明的是另一件事: 在弱网、拥塞、异常输入、频繁重连和服务退出时,网络库仍然可以给出精确、确定、可观察的行为。 这不是一次简单升级,而是 MsgTrans 从多协议网络库迈向生产级实时传输基础设施的重要一步。

查看原文
分享到:

相关推荐

国家数据局:词元市场需求呈现爆发式增长

刚刚

国家数据局:算力网与“五张网”形成深度耦合

刚刚

程一笑:快手持续创作超10年的作者超过1700万

刚刚

适用于 Win10 的最后一版英伟达 GeForce Game Ready 显卡驱动将于 10 月发...

刚刚