Cap'n Proto 是一种数据序列化格式和远程过程调用(RPC)框架,用于在计算机程序间交换数据。其高层设计注重速度与安全性,适用于网络通信及进程间通信。该框架由谷歌Protocol Buffers的前维护者(肯顿·瓦尔达)创建,旨在解决Protocol Buffers的某些设计缺陷。
技术概览[编辑 | 编辑源代码]
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] 模板:Expand section 截至 2020 年 10 月,其参考实现仅支持第 2 级。[13]
其他序列化格式[编辑 | 编辑源代码]
Cap'n Proto RPC常被拿来与其他零拷贝序列化格式相比较。例如谷歌的 FlatBuffers 和简单二进制编码(SBE)。[16][17]
应用案例[编辑 | 编辑源代码]
Cap'n Proto 最初是为 Sandstorm.io 创建的,这是一家提供基于能力安全的 Web 应用托管平台的初创公司。在 Sandstorm.io 商业化失败后,其开发团队被 Cloudflare 收购[18],后者在内部使用该框架。[19]
注释[编辑 | 编辑源代码]
参考文献[编辑 | 编辑源代码]
Category:数据序列化格式 Category:远程过程调用 Category:进程间通信
引用错误:名称为“注”的group(分组)存在<ref>
标签,但未找到对应的<references group="注"/>
标签