作者:雨过后放晴 | 来源:互联网 | 2023-05-19 07:51
在Web开发中,难免遇到需要跨语言甚至跨平台进行通信的场景,不论是PHP到C还是PHP到Java,或者C到Java,都需要双方有一个约定的协议来打包和解包所传输的数据。双方自定义的协议固然效率高,但是
在Web开发中,难免遇到需要跨语言甚至跨平台进行通信的场景,不论是PHP到C还是PHP到Java,或者C到Java,都需要双方有一个约定的协议来打包和解包所传输的数据。双方自定义的协议固然效率高,但是通用性差,因此便出现了本文将要讨论的这些通用的、跨平台的数据打包协议。这些协议各有特点,应用场景也不尽相同,本文试图从某些我们经常会关注的角度来对这些序列化协议进行比较,以期能够为我们做技术选型提供指导。
文中提到的这些东西,可以说是协议、工具或者类库,因为他们都包含:一个数据序列化/反序列化协议&实现改功能的代码,有些还提供了发布RPC Service的API。所以当你看到我用不同方式称呼它们的时候不要觉得困惑。
关于这些协议:
首先我们简单看一下这些协议的官方介绍,大致对他们有一些了解。
MessagePack:
MessagePack is a binary-based efficient object serialization library. It enables to exchange structured objects between many languages like JSON. But unlike JSON, it is very fast and small.
MessagePack(以下简称MP)是一种基于二进制的对象序列化协议和库。它像JSON一样可以用于在多种语言之间交换结构化的数据,但是不同的是它比JSON更小更快。并且MP也提供了远程调用(RPC)功能
Avro:
Apache Avro™ is a data serialization system.
Apache Avro是一个二进制的数据序列化系统。介绍够简单,实际上Avro除了序列化之外,像MP一样也提供了远程调用(RPC)功能。Avro是属于Hadoop的一个子项目,由Hadoop的 创始人Doug Cutting牵头开发,设计用于支持大批量数据交换的应用。
Thrift:
The Apache Thrift software framework, for scalable cross-language services development, combines a software stack with a code generation engine to build services that work efficiently and seamlessly between C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Javascript, Node.js, Smalltalk, OCaml and Delphi and other languages.
Thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发。它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Javascript, Node.js, Smalltalk, and OCaml 这些编程语言间无缝结合的、高效的服务。
Thrift是由Facebook主导开发的,目前也是Facebook的核心系统之一。
Protocol Buffers:
Protocol Buffers are a way of encoding structured data in an efficient yet extensible format. Google uses Protocol Buffers for almost all of its internal RPC protocols and file formats.
Protocol Buffers(以下简称PB)是Google开发的一种数据描述语言,高效、可扩展。Google内部远程调用以及数据存储大量使用了PB的结构。PB仅仅是一个序列化协议,并不包含RPC部分。
JSON:
JSON (Javascript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate.
JSON的官方介绍很长,因为大家都比较熟悉,我没有全截取下来。和上面几个不同的是,JSON是纯文本格式的,无疑在可读性上JSON是最好的。并且JSON因为出现的比较早,目前应用范围也是非常的广泛。
更多的信息,大家可以移步各官方网站,上面有比较全的介绍和示例什么的,对于想深入了解非常有帮助。
语言支持:
因为我们需要的是跨平台跨语言的协议,所以它们所能支持的语言是我们必须关注的。在每一个协议的官网上都列出了长长一串所支持的语言列表,因为工作环境,我并用不到这么多语言,所以后面我也不会挨个去尝试这些语言。但这里作为总体介绍,我姑且把这些语言都整理出来(有些实在是太冷门了,我都不知道是什么):
MP Avro Thrift PB JSON
ActionScript N N Y Y Y
ASP N N N N Y
Bash N N N N Y
BlitzMax N N N N Y
C Y Y Y Y Y
C++ Y Y Y Y Y
C# Y Y Y Y Y
Clojure N N N Y Y
Cobol N N N N Y
ColdFusion N N N N Y
D Y N Y Y Y
Delphi N N Y N Y
E N N N N Y
Erlang Y N Y Y Y
Fantom N N N N Y
Go Y N Y Y Y
Haskell Y N Y Y Y
haXe N N N N Y
Java Y Y Y Y Y
Javascript Y N Y Y Y
Lasso N N N N Y
Lisp N N N Y Y
LotusScript N N N N Y
Lua Y N N Y Y
Matlab N N N Y Y
Mercury N N N Y N
Node.js Y N Y N Y
Objective C N N Y Y Y
Ocaml Y N Y Y Y
OpenLaszlo N N N N Y
Perl Y Y Y Y Y
PHP Y Y Y Y Y
Pike N N N N Y
PL/SQL N N N N Y
PowerShell N N N N Y
Prolog N N N N Y
Puredata N N N N Y
Python Y Y Y Y Y
QT N N N N Y
R N N N Y Y
Racket N N N N Y
Rebol N N N N Y
RPG N N N N Y
Ruby Y Y Y Y Y
Scheme N N N N Y
Squeak N N N N Y
Symbian N N N N Y
Scala Y N N Y N
Smalltalk N N Y N N
Tcl N N N N Y
Visual Basic N N N Y Y
Visual FoxPro N N N N Y
列表老长老长,我想没人能够对上面的全都掌握吧。根据我的工作需要,我将只关注C/C++、Java、PHP这三种语言,后面的介绍和分析都将围绕这三个语言的环境来进行。幸运的是,我要比较的这些工具都支持这三种语言。
关于测试用例:
后面所有的测试中,为了使测试尽量公平我都将使用统一的测试用例。因为JSON是目前最最广泛使用的格式,我的测试都将以JSON作为基准进行。我将通过一些PHP程序生成所需要的测试用例,并以JSON格式保存。考虑到生产环境中经常遇到的情况,我构造了以下几种测试用例:
用例一(少量简单数据):
有时候我们的项目接口只会交互很小的数据量,比如一个单独的整型数。仿照这种情况,我定义一个仅包含几种普通数据类型各一的结构:
用例二(大量简单结构数据):
用例二模仿我们调用某个批量接口获取批量数据,我们要传入大量的ID或者Key,这里我构造了一个包含10000个ID的数组:
用例三(大量复杂结构数据):
批量接口返回的数据,我构造了一个member结构,随机生成里面的内容,循环生成10000个这样的结构模拟批量接口的返回的数据。
用例四(单条巨复杂结构数据):
有时候我们可能会请求一个字典,字典格式是key=>value格式,这类似于一个有n多字段的单条数据。尽管这个类比不是很合适,但是我们测试avro和thrift的时候就会发现这个测试用例还是挺有必要的。这里我生成一个具有10000个字段的单条数据。