- 手艺 tags:
- java
- sergent
- work published: true comments: true
The post is brought to you by lekhonee v0.7
糖果项目的后端用Java编写,我负责service gateway的开发(暂且叫sergent),服务以Java接口+Annotation的形式声明,与Spring集成使用,Java对象被序列化为JSON和XML(通过jackson和castor)与外部系统交互。专门的JSON Schema和XML Schema是可选的,系统交互通过简明的文档和人工确认。
RPC框架是跨进程、跨系统交互的重要工具,RPC框架中又包括远程调用、网络传输和序列化反序列化等等部分。流行的工具包括Facebook的thrift,Google的Protobuf和原先Hadoop项目下的avro。其中thrift包含远程调用、反序列化、网络等等全部的功能。Protobuf本身是一个序列化反序列化库,另有很多第三方RPC实现,avro目前除了序列化和反序列化的功能,也包含了ipc的HTTP Server和SocketServer等实现。在序列化的格式方面,Thrift支持JSON和二进制协议,Protobuf本身仅有二进制支持,但已经存在第三方的其他格式实现。 avro原生支持二进制和JSON格式。
从效率上来说,二进制方式的序列化要比文本方式的快。Google Code上(最近迁往了github)有一个tpc项目(thrift-protobuf-compare),根据这个项目的最新的比较结果(与原先不同):
protobuf成为了三者中耗时最少的框架,之后是thrift和avro,这次avro的耗时甚至超过了文本方式的jackson(主要在反序列化上)。
但是二进制协议通常都需要定义Schema,thrift / protobuf / avro三者各自定义了Schema的格式,没有类似XSD和Json Schema的统一标准,也就是说,当你需要传输一个对象,就要为它编写一个Schema文件。按照通常的习惯,都是先编写Schema,然后通过命令行工具或者自动构建工具来生成Java source。对于新系统还好说,对旧系统这个改造就比较麻烦了。另外,二进制协议不便于调试,所以各个thrift/protobuf/avro先后也都有JSON的实现,在文本的序列化格式上,JSON对XML的优势是全方位的。
所以综合起来,很难说有一种完美的解决方案。二进制协议的效率高,但是改造、编写Schema的代价并不小,还要面对核心Model被绑架到具体框架的风险。文本协议开发简便,不需要Schema,直接POJO就可以序列化和反序列化,但是在时间和空间上都不如二进制的方式。
补充
从tpc项目的结果上看,kryo在时间、空间上都击败了所有对手,而且,kryo的API非常简洁,不需要Schema文件就可以序列化POJO,听起来太完美了,看来以后sergent要借鉴一下的。
补充 2010-06-14 发现avro现在也有ReflectDatumReader和ReflectDatumWriter,可以通过反射内部自动映射生成Schema,可以尝试一下。