背景:

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

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

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

问题:

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

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

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

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

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

业界考察:

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

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

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

  1. 编码的压缩,采用Base128Varints序列化数字,减少网络传输开销。

  2. 非自描述数据,protocolbuffers将每个数据结构的描述信息嵌入到代码中,因此只需要传输数据过来,就可以反序列化出来该数据结构的实例了。

  3. Immutableobject,protocolbuffers在生成的java代码中采用builder&message模式,message是一个不能变的对象,即只有getter,没有setter,而每一个message的生成由一个对应的builder来完成,从这点可以看出,google已经用上了函数式编程。

  4. Rpc异步话,虽然protocolbuffers的rpc很简陋,但是一开始就只提供异步callback调用形式,可见google已经实现异步话,如果在互联网行业的人会知道,这点是相当不容易。

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

Thriftisasoftwareframeworkforscalablecross-languageservicesdevelopment.ItcombinesasoftwarestackwithacodegenerationenginetobuildservicesthatworkefficientlyandseamlesslybetweenC++,Java,Python,PHP,Ruby,Erlang,Perl,Haskell,C#,Cocoa,Smalltalk,andOCaml.

说得很清楚是一个跨语言的服务开发框架。包括的功能有codegeneration(代码生成,protocolbuffers也有),cross-language(跨语言,protocolbuffers也有),servicedevelopment(好吧,这个protocolbuffers也有)。晕倒,这样看起来,它和googleprotocolbuffers完全是同一个领域的东西,而其有点重复发明轮子的味道。

刚开始,我们也有这样一个疑惑,好吧,接着往下看,herewego。其实除了这些共同性以外(都是解决跨语言问题嘛),thrift还是和protocolbuffers有很大不同的。不同点如下:

1)提供一个完整的servicestack,定义了一整套的rpc服务框架栈,这个protocolbuffers是没有,这个绝对是thrift的利器,如果你想要开发一个服务,thrift甚至有个栈层的实现,我靠,爽。

2)Ok,在thrift论文有这样一句话。Thriftenforcesacertainmessagingstructurewhentransportingdata,butitisagnostictotheprotocolencodinginuse.嗯哼,我懂了,它是不会管,你到底采用哪种序列化方式的,hessian,xml甚至是protocolbuffers。Oh,mygod。

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

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

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

总结一下从Facebookthrift学到的东西:

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

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

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

ApacheHadoopavroAvroisadataserializationsystem.AvroprovidesfunctionalitysimilartosystemssuchasThrift,ProtocolBuffers,etc.好吧它自己都承认了,我们就不去纠结了。

简单介绍一下,avo是hadoop项目下面用来传输数据的一个架构。也是一个跨语言解决方案。不过avro有自己的亮点。1,Dynamictyping,2,Untaggeddata,3,.Nomanually-assignedfieldIds

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

解决方案:

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

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

2)采用thrift的service生成格式,以及实现兼容jbo***emoting或者springremoting的thrift(jbo***emoting)stack。

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

Ok了,一切看起来是那样的完美。呵呵,不要被迷惑,还有很多detail的事情需要解决,时候不早,吃碗泡面,洗洗睡了,有时间,再把具体实现detail分享给大家。

10/24/20101:22AM小丑鱼

转载于:https://blog.51cto.com/aliapp/1327661

Java跨语言调用实现方案相关推荐

  1. Java如何跨语言调用Python/R训练的模型

    在 如何使用sklearn进行在线实时预测(构建真实世界中可用的模型) 这篇文章中,我们使用 sklearn + flask 构建了一个实时预测的模型应用.无论是 sklearn 还是 flask,都 ...

  2. 使用thrift进行跨语言调用(php c# java)

    1:前言 实际上本文说的是跨进程的异构语言调用,举个简单的例子就是利用PHP写的代码去调C#或是java写的服务端.其实除了本文提供的办法还有其他办法,例如http+xml(json)等等都能做到. ...

  3. HarmonyOS之JS/Java跨语言调试

    在 HarmonyOS 应用开发中,通常会涉及到使用 JS 和 Java 语言同时开发的场景,一般使用 JS 来开发应用的 UI,使用 Java 开发应用的逻辑,JS FA 调用 Java PA.针对 ...

  4. 跨语言调用Hangfire定时作业服务

    背景 Hangfire允许您以非常简单但可靠的方式执行后台定时任务的工作.内置对任务的可视化操作.非常方便. 但令人遗憾的是普遍都是业务代码和hagnfire服务本身聚合在一个程序中运行,极大的限制了 ...

  5. JS 与 JAVA 跨语言实现 RSA 和 AES加密算法

    简介: 开发中为了数据的安全性使用加密算法对数据进行加密是一种很常见的情况,但就一种语言来说,直接使用提供的相应的库进行少许封装是一件很容易的事.但是在一些情况下我们可能需要跨语言来实现,比如前后端分 ...

  6. Dubbo 跨语言调用神兽:dubbo-go-pixiu

    简介:Pixiu 是基于 Dubbogo 的云原生.高性能.可扩展的微服务 API 网关.作为一款网关产品,Pixiu 帮助用户轻松创建.发布.维护.监控和保护任意规模的 API ,接受和处理成千上万 ...

  7. java 跨类 调用 model_Model.java中的这两个方法,为什么不能在子类中调用,或者包内调用也行啊。...

    @JFinal 你好,想跟你请教个问题: Model.java中的这两个方法,为什么不能在子类中调用,或者包内调用也行啊. /** * Find model. */ @SuppressWarnings ...

  8. jsb调用java_cocos2dx-jsb 跨语言调用及第三方集成 - 过程记录

    1:C++中调用js方法: 问题:ios中当用户通过home键将游戏转入后台时,调用js中的暂停游戏方法: AppDelegate::applicationDidEnterBackground() 和 ...

  9. EasyPlayerPro(Windows)流媒体播放器开发之跨语言调用

    下面我们来讲解一下关于EasyPlayerPro接口的调用,主要分为C++和C#两种语言,C++也可以基于VC和QT进行开发,C++以VC MFC框架为例进行讲解,C#以Winform框架为例进行讲解 ...

  10. java跨库调用存储_存储库仅在第二个调用数据时发送回ViewModel

    问题: My Fragment仅在第二次调用时获取数据(例如,当我旋转屏幕时) . 在我看来,这些代码行是repo类中的问题: public class UserRepository { privat ...

最新文章

  1. 构建超级智能未来系统的三原则
  2. 南昌理工学院计算机系考研,南昌理工学院的学生可不可以考研和公务员
  3. 未安装在此服务器场中,无法添加到该范围
  4. Javascript添加收藏夹和设为首页兼容写法
  5. 阿里技术官最新总结一份105道Java面试题小册,看完我惊呆了
  6. 一个简单的 Generic Factory 类
  7. 复杂风控场景下,如何打造一款高效的规则引擎
  8. Servlet JSP : web.xml 配置学习
  9. 【VMware虚拟机】使用SSH连接VMware上的Linux虚拟机(主机互通也可访问外网)
  10. 【java基础知识】java打包运行时显示控制台内容
  11. python的ols_Python Statsmodels 统计包之 OLS 回归
  12. dj打碟怎么学_关于DJ入门以及手把手教你如何打碟(转)
  13. 微信小程序授权登录(获取微信头像并显示)
  14. 七款好看文字样式纯css
  15. php中 号是什么意思,双问号(??)运算符在PHP中是什么意思
  16. 软件项目管理案例复习题
  17. 如何在Chrome中自定义新标签页
  18. pygame UI 框架
  19. python项目实战:爬取东方财富热门股票数据
  20. ubuntu文件系统字体底纹含义

热门文章

  1. Android下基于UVC的UsbCam的开发
  2. ubuntu11.10 sources.list 资源
  3. android gms包找不到,错误:包com.google.android.gms.appstate不存在
  4. java default修饰符_Java学习笔记--- 变量类型,修饰符
  5. 二元置信椭圆r语言_医学统计与R语言:Logistic Distribution
  6. 【数据结构】图文例题详解单调栈与单调队列
  7. NYOJ题目79-拦截导弹(最长递减子序列)
  8. ASP.NET----web用户控件
  9. jquery实现截取pc图片_html+jquery实现简单图片裁剪
  10. 结构体全局变量_nginx源码分析—内存池结构ngx_pool_t及内存管理