`
wbj0110
  • 浏览: 1554274 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

Java跨语言调用实现方案(转)

阅读更多

背景:

在大型分布式 java 应用中,为了方便开发者,通常底层的 rpc 框架都会做一些调用的封装,让应用层开发人员在开发服务的时候只用编写简单 的 pojo 对象就可以了,如流行的 spring remoting , jboss remoting 等等,都有这样的效果。

随着业务的需要,可能上层应用希望采用非 java 技术,如 php , ruby on rails ,而由于 java gc 和内存模型的限制,可能有的底层服务又需要采用更高性能和更加灵活的技术,如果 c++ , python 等。

这时候就会考虑跨语言的问题了,在如何不改动原有 pojo 实现的 rpc 框架,而让系统实现跨语言,这个难题摆在了中间件开发者的头上。

问题 :

现在我们不妨把上面说涉及的问题提取出来:

1)  不能改变原有的 java rpc 服务的发布方式,仍然采用 pojo 。

2)  上层非 java 应用可以调用到由 server 端 pojo 形式发布的服务。

3)  底层非 java 应用,如 c++ , python 等可以发布格式和 pojo service 一样的服务

4)  提供优雅的借口给应用开发者。

业界考察:

好在我们并不是第一个遇到这个问题的人,那我们来看看在我们业界的前辈们都给我们留下了哪些宝贵的财富(主要是互联网行业)。

Google protocol buffers Google 大神 总是早人一步,在 google 架构的初期就意识到了跨语言的重要性,在构建 bigtable , GFS 的同一时期就是定制出了一套跨语言方案。 那就是 google protocol buffers ,不过直到 08 年, google protocl buffers 才开源出来,正所谓国之利器不可以示人,我们所看到的, google protocl buffers 其实是阉割版,如没有 map 的支持 ( 根据一些资料表明, google 内部是有这个东西 的) , python 的 native c 性能优化,不包括 rpc service ,虽然后面补了一个,但是可用性差强人意,不能多参,不能抛异常。不过在这方面我们确实不应该报太大的希望,因为 google 自己都 说了 protocol buffers – a language-neutral, platform-neutral, extensible way of serializing structured data ,好吧,他只是一个序列化格式,而和 hessian , java 序列化有所不同的是, protocol buffers 可以用通过定义好数据结构的 proto ( IDL )文件产生目标语言代码,大大了减少了开发量,不过遗憾的是生成的代码有很强的侵 入性,并不能产生我们需要的pojo java 对象。

不过即使是这样,我们也从 google  protocol buffers 身上学到了很多东西。

  1. 编码的压缩,采用 Base 128 Varints 序列化数字,减少网络传输开销。
  2. 非自描述数据, protocol buffers 将每个数据结构的描述信息嵌入到代码中,因此只需要传输数据过来,就可以反序列化出来该数据结构的实例了。
  3. Immutable object , protocol buffers 在生成的 java 代码中采用 builder&message 模式, message 是一个不能变的对象,即只有 getter ,没有 setter ,而每一个 message 的生成由一个对应的 builder 来完成,从这点可以看出, google 已经 用上了函数式编程。
  4. Rpc 异步话,虽然 protocol buffers 的 rpc 很简陋,但是一开始就只提供异步 callback 调用形式,可见 google 已经实现异步话,如果在互联网行业的人会知道,这点是相当不容易。

Facebook thrift 4 月 1 号,呵呵,没 错, thrift 是 Facebook 于 07 年愚人节开源出来的,有点 google 的作风。 Thrift 是facebook 自己的一 套跨语言实现。有人会问这个和 protocol buffers 有啥区别。 Ok ,先看看它的定义吧。

Thrift is a software framework for scalable cross-language services development. It 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, 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)  提供一个完整的 service stack ,定义了一整套的 rpc 服务框架栈,这个 protocol buffers 是没有,这个绝对是 thrift 的利器,如果你想要开发一个服务, thrift 甚至有个栈层的实现,我靠,爽。

2)  Ok ,在 thrift 论文有这样一句话。 Thrift enforces a certain messaging structure when transporting data, but it is agnostic to the protocol encoding in use. 嗯哼,我懂了,它是不会管,你到底采用哪种序列化方式的,hessian ,xml 甚至是protocol buffers 。Oh ,my god 。

3)  接下来不得不膜拜一下thrift 的service 接口的强大了,多参,异常,同步,异步调用的支持,这正是我们想要的, 瞬间给protocol buffers 比下去了。

4)  多集合的支持 map , set 都有,让你爽歪歪。 Protocol buffers 颤抖吧。

这时候我们亲爱的读者就会问了,那我们的问题不就解决了吗,就是 thrift 。我笑而不语 , 虽然 thrift 是如此的强大,但是它仍然 不是我们想要的, thrift 生成的代码也是强侵入性的,这样 pojo 的对象是无法发布服务的。还有一个硬伤是虽 然 thrift 的 stack 很强大,当时这和我们原有系统的 stack 肯定是不兼容的,如 jboss remoting , spring remoting ,它们都会加一些 header 信息,而 thrift 已有实现的传输中式没有header 信息的。值得一提的是现有 的 thrift service 实现中,不是线程安全的,考虑到有些语言没有对线程很好的支持,尤其是 Facebook 最常用的 PHP 语言,所以现有的实现中没 有线程安全 Client 的实现。这样就会造成 client 端 connection 不能复用的问题,相当于短连接了。( ps :其实短连接就 真的比长连接性能差吗?这是个问题。)

总结一下从 Facebook thrift 学到的东西:

1)              同步,异步都支持,这个很强悍,一般的做法是对性能要求高的服务器端采用异步方式开发,对易用性有要求的客户端采用同步方式调用,是比较完美的。

2)              从现有的非线程安全的实现看, Facebook 很有可能自己有一套更高效的线程安全的实现,估计考虑到和 thrift 关系不到,或者是核心技术,所以没有放出来,其实想自己做,也不是太难。

3)              Thrift 对很多脚本语言都进行了 native c 的性能优化,如 python 端,采用 native c 以后性能提高 20 倍。 Protocol buffers 一直在做这方面的优化,打算在 2.4 中加入,不过 protocol buffers 就像 jdk 7 一样难产,跟让人崩溃的是,前不久在论坛爆出做这块优化的哥们已经离开了 google ,不再负责了,好吧,我关心的是他去哪儿了,泪奔。

Apache Hadoop avro Avro is a data serialization system. Avro provides functionality similar to systems such as Thrift, Protocol Buffers, etc. 好吧它自己都承认了,我们就不去纠结了。

简单介绍一下, avo 是 hadoop 项目下面用来传输数据的一个架构。也是一个跨语言解决方案。不过 avro 有自己的亮点。 1 , Dynamic typing, 2 , Untagged data , 3 , . No manually-assigned field Ids

眼前一亮, Dynamic typing , oh , my god 。没错, avro 通过将 metadata 放在一个叫 schema 的对象里面,然后可以序列化对应的 pojo兑现。这个正是我想要 的,至于其他的特性,的确没有咋仔细看 avro ,感觉上比 thrift ,和 protocol buffers 跟难学习,有熟悉的读者可以给我科普一下。

解决方案:

好了,到了这里,读者大概心里也有数了, protocol buffers , thrift , avro 都有我们想要的和我们不想要的。要解决我们的问题,我们只需要扬长避短就可以了。揉揉就是我们的东西了。方案如下:

1)  采用 protocol buffers 的 message 序列化格式和代码生成。

2)  采用 thrift 的 service 生成格式,以及实现兼容 jboss remoting 或者 spring remoting 的 thrift ( jboss remoting ) stack 。

3)  原有的 pojo 对象采用 avro 的 schema 方式序列化和反序列化该对象。

分享到:
评论

相关推荐

    java开源包1

    JSTUN 是另外一个用来解决穿越 NAT 进行通讯的 Java 解决方案,是 STUN 协议的 Java实现。 在浏览器上运行Java程序 Doppio DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一...

    java开源包4

    JSTUN 是另外一个用来解决穿越 NAT 进行通讯的 Java 解决方案,是 STUN 协议的 Java实现。 在浏览器上运行Java程序 Doppio DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一...

    JAVA上百实例源码以及开源项目

    百度云盘分享 ... Java实现的FTP连接与数据浏览程序,实现实例化可操作的窗口。  部分源代码摘录:  ftpClient = new FtpClient(); //实例化FtpClient对象  String serverAddr=jtfServer.getText();...

    JAVA上百实例源码以及开源项目源代码

     Java实现的FTP连接与数据浏览程序,实现实例化可操作的窗口。  部分源代码摘录:  ftpClient = new FtpClient(); //实例化FtpClient对象  String serverAddr=jtfServer.getText(); //得到服务器地址  ...

    java开源包3

    JSTUN 是另外一个用来解决穿越 NAT 进行通讯的 Java 解决方案,是 STUN 协议的 Java实现。 在浏览器上运行Java程序 Doppio DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一...

    java开源包11

    JSTUN 是另外一个用来解决穿越 NAT 进行通讯的 Java 解决方案,是 STUN 协议的 Java实现。 在浏览器上运行Java程序 Doppio DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一...

    java开源包6

    JSTUN 是另外一个用来解决穿越 NAT 进行通讯的 Java 解决方案,是 STUN 协议的 Java实现。 在浏览器上运行Java程序 Doppio DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一...

    java开源包9

    JSTUN 是另外一个用来解决穿越 NAT 进行通讯的 Java 解决方案,是 STUN 协议的 Java实现。 在浏览器上运行Java程序 Doppio DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一...

    java开源包101

    JSTUN 是另外一个用来解决穿越 NAT 进行通讯的 Java 解决方案,是 STUN 协议的 Java实现。 在浏览器上运行Java程序 Doppio DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一...

    java开源包5

    JSTUN 是另外一个用来解决穿越 NAT 进行通讯的 Java 解决方案,是 STUN 协议的 Java实现。 在浏览器上运行Java程序 Doppio DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一...

    java开源包8

    JSTUN 是另外一个用来解决穿越 NAT 进行通讯的 Java 解决方案,是 STUN 协议的 Java实现。 在浏览器上运行Java程序 Doppio DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一...

    java开源包10

    JSTUN 是另外一个用来解决穿越 NAT 进行通讯的 Java 解决方案,是 STUN 协议的 Java实现。 在浏览器上运行Java程序 Doppio DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一...

    安卓平台下用200行java代码实现音视频通话

    最近学习Android平台下跨平台音视频通信开发,在国内我找到了一个比较好音视频通信解决方案,该案例提供了纯Java语言接口供我们调用,随后我参照官方android demo程序和开发文档并结合自己的见解写了一个android音频...

    java开源包2

    JSTUN 是另外一个用来解决穿越 NAT 进行通讯的 Java 解决方案,是 STUN 协议的 Java实现。 在浏览器上运行Java程序 Doppio DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一...

    java开源包7

    JSTUN 是另外一个用来解决穿越 NAT 进行通讯的 Java 解决方案,是 STUN 协议的 Java实现。 在浏览器上运行Java程序 Doppio DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一...

    Java资源包01

    JSTUN 是另外一个用来解决穿越 NAT 进行通讯的 Java 解决方案,是 STUN 协议的 Java实现。 在浏览器上运行Java程序 Doppio DoppioVM 是一个可在浏览器上直接运行 Java 项目的系统,无需任何插件支持。目前它包含一...

    java 面试题 总结

    它是基于Java的远程方法调用(RMI)技术的,所以EJB可以被远程访问(跨进程、跨计算机)。但EJB必须被布署在诸如Webspere、WebLogic这样的容器中,EJB客户从不直接访问真正的EJB组件,而是通过其容器访问。EJB容器是...

    c++访问webservice

    我们已经知道如何在java端调用web服务(见web服务使用说明文档),但是如何在其他平台的其他客户端调用我们的web服务呢?下面做一下简单介绍并通过Gsoap举一个请求服务的例子。 WebService是一种跨平台的解决方案。...

    JAVA课程设计扑克游戏.doc

    设计方案论证 设计思路 用java语言,编程实现纸牌游戏,拥有如下规则,将电脑多次分发给你的 牌按照相同的花色大至小排列起来。游戏分为三个难度,简单,普通,困难。简单为单 一花色。困难所分发给的牌有四种花色...

Global site tag (gtag.js) - Google Analytics