Java跨语言调用实现方案
?
Java跨语言实现方案在大型分布式java应用中,为了方便开发者,通常底层的rpc框架都会做一些调用的封装,让应用层开发人员在开发服务的时候只用编写简单的pojo对象就可以了,如流行的spring remoting,jboss remoting等等,都有这样的效果。
好在我们并不是第一个遇到这个问题的人,那我们来看看在我们业界的前辈们都给我们留下了哪些宝贵的财富(主要是互联网行业)。
Google protocol buffers:Google大神总是早人一步,在google架构的初期就意识到了跨语言的重要性,在构建bigtable,GFS的同一时期就是定制出了一套跨语言方案。那就是google protocol buffers,不过直到08年,googleprotocl buffers才开源出来,正所谓国之利器不可以示人,我们所看到的,google protocl buffers其实是阉割版,如没有map的支持(根据一些资料表明,google 内部是有这个东西的),python的native c性能优化,不包括rpc service,虽然后面补了一个,但是可用性差强人意,不能多参,不能抛异常。不过在这方面我们确实不应该报太大的希望,因为google自己都说了protocol buffers a language-neutral, platform-neutral, extensible way of serializingstructured data,好吧,他只是一个序列化格式,而和hessian,java序列化有所不同的是,protocol buffers可以用通过定义好数据结构的proto(IDL)文件产生目标语言代码,大大了减少了开发量,不过遗憾的是生成的代码有很强的侵入性,并不能产生我们需要的pojo java对象。
不过即使是这样,我们也从google? protocol buffers身上学到了很多东西。
- ? 编码的压缩,采用Base128 Varints序列化数字,减少网络传输开销。Facebook thrift:4月1号,呵呵,没错,thrift是Facebook于07年愚人节开源出来的,有点google的作风。Thrift是facebook自己的一套跨语言实现。有人会问这个和protocol buffers有啥区别。Ok,先看看它的定义吧。
Thrift is asoftware framework for scalable cross-language services development. Itcombines a software stack with a code generation engine to build services thatwork efficiently and seamlessly between C++, Java, Python, PHP, Ruby, Erlang,Perl, Haskell, C#, Cocoa, Smalltalk, and OCaml.
说得很清楚是一个跨语言的服务开发框架。包括的功能有code generation(代码生成,protocol buffers也有),cross-language(跨语言,protocol buffers也有),service development(好吧,这个protocol buffers也有)。晕倒,这样看起来,它和google protocol buffers完全是同一个领域的东西,而其有点重复发明轮子的味道。
刚开始,我们也有这样一个疑惑,好吧,接着往下看,here we go。其实除了这些共同性以外(都是解决跨语言问题嘛),thrift还是和protocol buffers有很大不同的。不同点如下:
1)? 提供一个完整的servicestack,定义了一整套的rpc服务框架栈,这个protocol buffers是没有,这个绝对是thrift的利器,如果你想要开发一个服务,thrift甚至有个栈层的实现,我靠,爽。

??????????????? 图1:thriftservice stack
?
2)? Ok,在thrift论文有这样一句话。Thriftenforces a certain messaging structure when transporting data, but it isagnostic to the protocol encoding in use. 嗯哼,我懂了,它是不会管,你到底采用哪种序列化方式的,hessian,xml甚至是protocolbuffers。Oh,my god。
3)? 接下来不得不膜拜一下thrift的service接口的强大了,多参,异常,同步,异步调用的支持,这正是我们想要的,瞬间给protocol buffers比下去了。
4)? 多集合的支持map,set都有,让你爽歪歪。Protocolbuffers颤抖吧。
?
总结一下从Facebook thrift学到的东西:
1)?????????????同步,异步都支持,这个很强悍,一般的做法是对性能要求高的服务器端采用异步方式开发,对易用性有要求的客户端采用同步方式调用,是比较完美的。
2)?????????????从现有的非线程安全的实现看,Facebook很有可能自己有一套更高效的线程安全的实现,估计考虑到和thrift关系不到,或者是核心技术,所以没有放出来,其实想自己做,也不是太难。
3)?????????????Thrift对很多脚本语言都进行了nativec的性能优化,如python端,采用native c以后性能提高20倍。Protocol buffers 一直在做这方面的优化,打算在2.4中加入,不过protocol buffers就像jdk 7一样难产,跟让人崩溃的是,前不久在论坛爆出做这块优化的哥们已经离开了google,不再负责了,好吧,我关心的是他去哪儿了,泪奔。
Apache Hadoop avro:Avro is a data serialization system. Avro provides functionalitysimilar to systems such as Thrift, Protocol Buffers, etc.好吧它自己都承认了,我们就不去纠结了。
眼前一亮,Dynamic typing,oh,my god。没错,avro通过将metadata放在一个叫schema的对象里面,然后可以序列化对应的pojo兑现。这个正是我想要的,至于其他的特性,的确没有咋仔细看avro,感觉上比thrift,和protocol buffers跟难学习,有熟悉的读者可以给我科普一下。
好了,到了这里,读者大概心里也有数了,protocolbuffers ,thrift, avro都有我们想要的和我们不想要的。要解决我们的问题,我们只需要扬长避短就可以了。揉揉就是我们的东西了。方案如下:
1)? 采用protocolbuffers的message序列化格式和代码生成。
2)? 采用thrift的service生成格式,以及实现兼容jbossremoting或者spring remoting的thrift (jboss remoting)stack。
3)? 原有的pojo对象采用avro的schema方式序列化和反序列化该对象。
Ok了,一切看起来是那样的完美。呵呵,不要被迷惑,还有很多detail的事情需要解决,时候不早,吃碗泡面,洗洗睡了,有时间,再把具体实现detail分享给大家。
?
?
?
?
?本文?
淘宝JAVA中间件团队博客
的链接?http://rdc.taobao.com/team/jm/archives/389
?
?
打算试用google的pro buffer。非常感谢楼主的分享! 6 楼 CshBBrain 2010-10-25 呵呵,有这方面的需要可以考虑下phprpc,注意不是广告。不要被他的名字所迷惑,这是一个跨语言远程过程调用中间件。好像作者还有更强悍的商业版本。www.phprpc.org;目前正用这个实现php,js,j2ee之间的互联互通。效果还可以。 7 楼 CshBBrain 2010-10-25 这个可是国产的哈。 8 楼 ray_linn 2010-10-25 那么多厂商争论那么多年才搞出SOAP这种公有协议,google和facebook的私有协议有嘛用? 9 楼 tangjwtj 2010-10-25 先MARK一下,再看具体内容 10 楼 coffeesweet 2010-10-25 一个SOAP都把人整的不知道该怎么写了,看谁NB吧? 11 楼 yuhui_bear 2010-10-25 yajun 威武!!!
围观党 +1 12 楼 yuhui_bear 2010-10-25 ray_linn 写道那么多厂商争论那么多年才搞出SOAP这种公有协议,google和facebook的私有协议有嘛用?
呵呵, 私有的大家都在用, 为什么要公共? 13 楼 wang_scu 2010-10-25 yuhui_bear 写道yajun 威武!!!
围观党 +1
都是师兄栽培得好。 呵呵。 14 楼 wang_scu 2010-10-25 CshBBrain 写道呵呵,有这方面的需要可以考虑下phprpc,注意不是广告。不要被他的名字所迷惑,这是一个跨语言远程过程调用中间件。好像作者还有更强悍的商业版本。
www.phprpc.org;目前正用这个实现php,js,j2ee之间的互联互通。效果还可以。
phprpc的确有考虑过,phprpc是一个很好的序列化格式,pb,thrift的不同在于,它通过idl生成各种语言的序列化,甚至是底层数据交互代码,这样大大的减少了开发量和开发难度,所以我们还是比较看重的是这一点,具体的序列化格式,phprpc的确是一个不错的选择。 15 楼 wang_scu 2010-10-25 coffeesweet 写道一个SOAP都把人整的不知道该怎么写了,看谁NB吧?
soap的确是个很好的东西,虽然没有仔细研究,呵呵,有机会科普一下吧,如果有更好的选择,我们会考虑的。 16 楼 diggywang 2010-10-26 phprpc是一个很好的选择啊! 17 楼 yangguo 2010-10-26 来人啊,把投新手帖的贼子拿下,
狗头铡伺候,开铡,斩!
18 楼 gqf2008 2010-10-26 ice或者phprpc的商业版,开源版本使用复杂类型上很痛苦! 19 楼 kokorodo 2010-10-26 嗯。确实,跨语言是比较麻烦一点。我现在也是在弄java调用python,不过我不知道这个和你说的一致不一致!有空大家讨论一下