Google的二进制编码格式:Protocol Buffers

Google不久前开源了一种数据交换格式——Protocol Buffers。在它语焉不详的名字背后,藏着的是:

  • 一种描述数据格式的IDL
  • 对IDL所描述的格式进行编码的一种二进制编码方案
  • 通过代码生成器实现的数据绑定支持,Google提供了C++、Python、Java实现

它的 IDL用来描述数据格式,下面是 来自Protocol Buffers项目网站的例子
message Person { 
required int32 id = 1;
required string name = 2;
 optional string email = 3;
}
要明确指定字段名称对应的序号(称为“tag”),才能在以后变更格式。如果用自动分配的序号,对格式的更改会引起麻烦(比如在中间插入一个新字段)。为什么呢?因为在二进制格式,tag是用来说明某段字节编码所表示的(协议描述里的)字段的。明确地分配tag序号,搭配上忽略未知tag的规则,在变更格式的时候就可以从容增加字段而不影响已有字段。

格式描述保存在.proto文件里,编译成源代码之后使用。Protocol Buffers发布的时候已经包括了对C++、Python和Java的支持。对其他语言的支持也正在进行之中,例如Ruby、Erlang、Perl、Haskell等等。有意增加其他语言支持的人都应该会很高兴有人已经将.proto文件的语法反向工程成了EBNF。

语言支持就是把.proto文件转换成目标语言的代码,组成映射到.proto文件所定义格式的一些类。有了语言支持就能从二进制数据中重组出对象,修改里面的字段,然后把对象的状态重新序列化成二进制格式。

一如以往Google发布新项目的情况, Protocol Buffers也激起了不小的骚动,占据了不少博客帖子。 Google的官方博客也解释了开发Protocol Buffers的原因,里头曾提到XML用作编码格式效率非常低。这种说法引来了潮水般的博客贴——有些认为Protocol Buffers意味着XML的结束,有些认为Protocol Buffers不如XML。 Ted Neward对现状做了如下总结
总而言之,如果你想要松散耦合的终端程序,保留最大的灵活性,那就接着用XML,包装进SOAP封包或者符合底层传输(也就是说HTTP,因为依赖其他传输形式的REST还没有真正被定义)要求的RESTful封包。 如果你需要二进制格式,Protocol Buffers是其中一个答案……但ICE也是,甚至CORBA(虽然参与者日少已经使它失去了吸引力)。不要仅仅由于贴上了Google的商标,就忽略了对技术优势和劣势的分析。

与XML或JSON的比较很容易使人忽略Protocol Buffers其实是对现有技术的重新实现。除了前面已经提到的,还有一项广泛使用的技术——ASN.1也是其竞争对手。ASN.1虽然已经存在了几十年,却不怎么显山露水。从用ASN.1描述的格式名单来看,这是非常奇怪的一件事情,请看看其中的几种格式:

  • X.509证书(许多系统的PKI都使用,包括SSL)
  • LDAP
  • Cryptographic Message Syntax(CMS)用于电子邮件加密
  • PKCS#1,用于RSA密匙
  • 3G电话网络

ASN.1的用途广泛;例如,日常的电信通信就用到ASN.1编码的数据。ASN.1基于与Protocol Buffers相似的概念——它也用IDL描述数据,用编译器为目标语言生成代码。但两者有一处关键差别——ASN.1允许多种编码方法,可以根据用途来选择。 Canonical Encoding Rules(CER)是其中的一种编码方式,其强制实行严格的编码规则,这对数字签名来说很关键,因为稍有差异就意味着很大的区别,其他可用的编码方式还有Packed Encoding Rules(PER)。 XML Encoding Rules(XER)允许将数据编码成XML,ASN.1也就成了与XML Schema并列的选项。Fast Web Services技术就能把XML Schemas映射成ASN.1,然后用ASN.1在端点之间进行编码效率更高的通信。

还有一种技术与Google的Protocol Buffers相似,那就是Facebook的Thrift,它的工作原理也差不多(见Protocol Buffers与Thrift的逐点对比)。Binary XML也是一种不太成功的类似技术,它已经在XML界酝酿了很久,但成功仍然遥遥无期。Erlang的创造者Joe Armstrong也在回答关于Protocol Buffers的问题时提到可以把UBF用作一种二进制格式直接传输程序字节码,无需解析。

这些技术共同的目标都是提高效率。有人可能觉得在线路上传输的数据量不是问题,因为有数据压缩技术。然而压缩/解压缩只是在使用数据前后执行的额外步骤,实际的解析过程中使用的仍然是没压缩的大量数据。对于XML来说,意味着一次又一次重复地读取同样的元素标签——简直与Protocol Buffers的数字标签没法比。当然,改善的程度取决于实际的格式。主要由字符串组成的格式效果就没有主要由数字数据组成的格式那么显著。

Mark Pilgirm也整理了一份对Protocol Buffer的反响。还有一个值得注意的方面,从Protocol Buffers身上可以看出一个RPC系统的蛛丝马迹。虽然目前还没有向大众公开,但在Steve Vinoski的博客上有一位Google的员工提到,Google内部确有这样一个RPC系统在担当重任。

你是否遇到过出于效率原因而考虑二进制格式的时候?如果是,你是自己搞一套还是找现有的技术?

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/14420698/viewspace-410106/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/14420698/viewspace-410106/

你可能感兴趣的:(java,python,ldap)