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身上学到了很多东西。
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分享给大家。
?
?
?
?
?本文?
的链接?http://rdc.taobao.com/team/jm/archives/389
?
?
打算试用google的pro buffer。非常感谢楼主的分享! 6 楼 CshBBrain 2010-10-25 呵呵,有这方面的需要可以考虑下phprpc,注意不是广告。不要被他的名字所迷惑,这是一个跨语言远程过程调用中间件。好像作者还有更强悍的商业版本。