草稿:Cap'n Proto
![]() | 正在审阅中
一名志愿者正在审阅这篇草稿,结果将会很快发布。
出于礼貌,请在显示此消息时不要编辑。添加此通知的用户将列在页面历史中。此消息旨在帮助减少编辑冲突,并避免审阅员重复彼此的工作。 | ![]() |
您所提交的草稿仍需改善。在2025年6月3日由Pathfinbird (留言)审阅。
如何改善您的草稿
| ![]() |
原作者 | 肯顿·瓦尔达(Kenton Varda) |
---|---|
源代码库 | github |
编程语言 | C++ |
类型 | 远程过程调用框架、序列化格式与库、IDL编译器 |
许可协议 | MIT许可证 |
网站 | capnproto |
Cap'n Proto 是一种数据序列化格式和远程过程调用(RPC)框架,用于在计算机程序间交换数据。其高层设计注重速度与安全性,适用于网络通信及进程间通信。该框架由谷歌Protocol Buffers的前维护者(肯顿·瓦尔达)创建,旨在解决Protocol Buffers的某些设计缺陷。
此條目過於依赖第一手来源。 (2025年6月3日) |
技术概览
[编辑]IDL模式
[编辑]与多数RPC框架(如早期的Sun RPC、OSF DCE RPC及其面向对象衍生品CORBA和DCOM)类似,Cap'n Proto使用接口描述语言(IDL)生成多种编程语言的RPC库,自动处理网络请求、数据类型转换等底层细节。其接口模式采用C语言风格语法,支持基础数据类型(布尔值、整数、浮点数等)、复合类型(结构体、列表、枚举)以及泛型和动态类型。[1]该框架还支持多重继承等面向对象特性,但因此被批评增加了复杂性。[2]
@0xa558ef006c0c123; # 手动或自动分配给文件和复合类型的唯一标识符
struct Date @0x5c5a558ef006c0c1 {
year @0 :Int16; # @n 标记了字段被添加的顺序
month @1 :UInt8;
day @2 :UInt8;
}
struct Contact @0xf032a54bcb3667e0 {
name @0 :Text;
birthday @2 :Date; # 字段可以添加到定义中的任何位置,但其编号必须反映它们被添加的顺序
phones @1 :List(PhoneNumber);
struct PhoneNumber { # 没有静态 ID 的复合类型不能被重命名,因为自动生成的 ID 是确定性的
number @0 :Text;
type @1 :PhoneType = mobile; # 默认值
enum PhoneType {
mobile @0;
landline @1;
}
}
}
Cap'n Proto 消息采用二进制编码,而非JSON或XML等文本格式。其设计目标是使存储/网络协议适合作为内存中的格式,从而避免将数据读入/写出内存时的转换步骤。[注 1]例如,数字的表示(字节序)采用主流CPU架构的表示方式。[3]当内存中的数据格式与网络传输协议格式相匹配时,Cap'n Proto 在创建或读取消息时就可以避免复制和编码数据,而是直接指向内存中值的位置。Cap'n Proto 还支持数据的随机访问,这意味着无需读取整个消息即可读取任何字段。[4]
与其他二进制序列化协议(如 XMI)不同,Cap'n Proto 认为在 RPC 层面进行细粒度的数据验证是一种反模式,会限制协议的演进能力。这一观点源于在谷歌的经验,在那里即使只是将字段从必填改为可选也会导致复杂的运维故障。[5][注 2]Cap'n Proto 模式被设计为尽可能灵活,并将数据验证推至应用层完成,允许任意重命名字段、添加新字段以及使具体类型泛型化。[6]然而,Cap'n Proto 在首次访问值时确实会验证指针边界并对单个值进行类型检查。[4]
强制执行复杂的模式约束还会带来显著的开销,[注 3] 抵消了重用内存数据结构的优势,并阻碍了对数据的随机访问。[7] Cap'n Proto 协议理论上适合[8]通过不可变共享内存实现非常快速的进程间通信(IPC),但截至 2020 年 10 月,尚无实现支持通过共享内存传递数据。[9] 尽管如此,Cap'n Proto 通常仍被认为比Protocol Buffers及类似的 RPC 库更快。[10][11]
网络特性
[编辑]Cap'n Proto RPC具备网络感知能力:支持连接中断处理和承诺流水线(将函数输出直接作为另一函数的输入),这为客户端省去了每次连续调用服务器所需的往返通信,而无需为每个可能的调用图提供专用 API。Cap'n Proto 当前支持基于TLS的传输[12],未来计划集成Noise Protocol Framework。[13]作为传输层无关协议,其主线实现支持WebSockets、HTTP、TCP和UDP。[14]
能力安全
[编辑]Cap'n Proto RPC 标准 拥有一个丰富的能力安全模型,该模型基于E 编程语言所使用的 CapTP 协议。[15]
![]() | 此章节需要扩充。 (2021年3月) |
截至 2020 年 10 月,其参考实现仅支持第 2 级。[13]
其他序列化格式
[编辑]Cap'n Proto RPC常被拿来与其他零拷贝序列化格式相比较。例如谷歌的 FlatBuffers 和简单二进制编码(SBE)。[16][17]
应用案例
[编辑]Cap'n Proto 最初是为 Sandstorm.io 创建的,这是一家提供基于能力安全的 Web 应用托管平台的初创公司。在 Sandstorm.io 商业化失败后,其开发团队被 Cloudflare 收购[18],后者在内部使用该框架。[19]
注释
[编辑]- ^ 与Apache Arrow不同,Cap'n Proto的内存值不适合共享可变数据
- ^ 必填字段标记在Protocol Buffers 3中已移除
- ^ 假设数据已经分配(例如在网络缓冲区中、从磁盘读取),访问复杂度变为 O(1)。额外的序列化/反序列化步骤(如检查值所需)会将性能限制在 O(n)。
参考文献
[编辑]- ^ Cap'n Proto模式语言. [2020-09-05]. (原始内容存档于2015-03-17).
- ^ 对Cap'n Proto模式语言的批评. [2020-10-10]. (原始内容存档于2019-06-26).
- ^ Cap'n Proto简介. [2020-11-09]. (原始内容存档于2015-03-17).
- ^ 4.0 4.1 Cap'n Proto编码规范. (原始内容存档于2015-03-17).
- ^ 常见问题§如何设置Protocol Buffers式的必填字段?. [2020-09-05]. (原始内容存档于2015-03-18).
- ^ 模式演化. [2020-10-10].
- ^ Cap'n Proto:Cap'n Proto、FlatBuffers 和 SBE. capnproto.org. [2020-10-10].
- ^ Richardson, Corey. Robigalia:现代时代的操作系统. robigalia.gitlab.io. October 2016 [2020-10-10]. (原始内容存档于2018-09-15).
- ^ Kenton, Varda. 为何不打算将内存状态放在 Cap'n Proto / Protobuf 对象中?. Hacker News (news.ycombinator.com). May 3, 2017 [2020-10-10].
- ^ Naughton, Chris. 协议基准测试. Github. Aug 24, 2018 [2020-09-05]. (原始内容存档于2018-08-30).
- ^ Parimi, Dinesh. 数据中心减税:通过协议缓冲区加速提升 WSC 效率 (PDF). 2019 [2020-09-05]. (原始内容存档 (PDF)于2020-09-06).
- ^ 路线图. [2020-10-10].
- ^ 13.0 13.1 RPC协议特性规划. [2021-03-13]. (原始内容存档于2015-03-17).
- ^ C++ RPC实现. [2020-10-10].
- ^ RPC协议特性. (原始内容存档于2015-03-18).
- ^ Cap'n Proto与FlatBuffers/SBE对比. [2020-10-10].
- ^ 为何选择 flatbuffers 而非 capnp?.
- ^ Sandstorm团队加入Cloudflare公告. [2020-09-05]. (原始内容存档于2017-03-13).
- ^ Lua-capnproto序列化优化. [2020-09-05]. (原始内容存档于2014-03-06).