一.背景
在大型分布式 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)提供优雅的借口给应用开发者。
二.业界考察
好在我们并不是第一个遇到这个问题的人,那我们来看看在我们业界的前辈们都给我们留下了哪些宝贵的财富(主要是互联网行业)。
1.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 身上学到了很多东西。
a. 编码的压缩,采用 Base 128 Varints 序列化数字,减少网络传输开销。
b. 非自描述数据, protocol buffers 将每个数据结构的描述信息嵌入到代码中,因此只需要传输数据过来,就可以反序列化出来该数据结构的实例了。
c. Immutable object , protocol buffers 在生成的 java 代码中采 用 builder&message 模式, message 是一个不能变的对象,即只有getter ,没有 setter ,而每一个 message 的生成由一个对应的 builder 来完成,从这点可以看出, google 已经用上了函数式编程。
d. Rpc 异步话,虽然 protocol buffers 的 rpc 很简陋,但是一开始就只提供异步 callback 调用形式,可见 google 已经实现异步话,如果在互联网行业的人会知道,这点是相当不容易。
2.Facebook thrift
thrift 是 Facebook 于 07 年4月1号开源出来的,有点 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 完全是同一个领域的东西,而其有点重复发明轮子的味道。其实除了这些共同性以外(都是解决跨语言问题嘛), thrift 还是和protocol buffers 有很大不同的,不同点如下:
1)提供一个完整的 service stack ,定义了一整套的 rpc 服务框架栈,这个 protocol buffers 是没有,这个绝对是 thrift 的利器,如果你想要开发一个服务, thrift 甚至有个栈层的实现,我靠,爽。
2)在 thrift 论文有这样一句话。 Thrift enforces a certain messaging structure when transporting data, but it is agnostic to the protocol encoding in use. 嗯哼,我懂了,它是不会管,你到底采用哪种序列化方式的,hessian ,xml 甚至是protocol buffers 。
3)接下来不得不膜拜一下thrift 的service 接口的强大了,多参,异常,同步,异步调用的支持,这正是我们想要的, 瞬间给protocol buffers 比下去了。
4)多集合的支持 map , set 都有,让你爽歪歪。 Protocol buffers 颤抖吧。
虽然 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 中加入。
3.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,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编程语言来实现MySQL与SQL Server之间的数据传递。Java以其强大的网络通信能力和丰富的库支持,成为这种任务的理想选择。 首先,我们需要理解MySQL和SQL Server这两个数据库系统。MySQL...
TransmittableThreadLocal 是一种专门为线程池设计的ThreadLocal解决方案,可以实现跨线程池之间的数据传递。它可以在多个线程池之间传递数据,解决了ThreadLocal 的局限性。 TransmittableThreadLocal 的实现原理...
本文主要探讨了如何使用JAVA语言和相关的技术来实现这一目标。JAVA因其平台无关性的特性,成为解决此类问题的理想选择。文章首先分析了局域网视频传输的特点和常见问题,如数据量大可能导致的网络拥塞和延迟。 文章...
例如,JSON因其简洁性和易读性,在跨语言数据交换中非常流行,Java中可以使用Jackson或Gson库进行JSON的序列化和反序列化。 在WOX开源项目中,可能提供了专门针对Java的序列化工具或API,帮助开发者更方便地处理...
Protobuf的消息定义文件(.proto)是文本格式,易于阅读和编辑,且可以跨语言共享。 在Netty中集成Protobuf,主要目的是利用Protobuf的数据序列化能力,将Java对象转换为字节流,然后通过Netty的Channel发送到网络...
Java 数据交换系统是数字化校园中的一种解决方案,可以实现学校内部管理人员、教师、学生之间的信息交换和数据传递。Java 作为一种跨平台、代码可移植、方便易学的编程语言,非常适合开发网络分布式应用程序。 ...
JSP的优势在于其高效率、跨平台的特性,以及与Java语言的紧密集成,确保了代码的可移植性。 3. **MVC(Model-View-Controller)架构**:MVC是一种软件设计模式,用于分离应用程序的业务逻辑、用户界面和数据管理。...
Java是一种跨平台、面向对象的编程语言,具有“一次编写,到处运行”的特性,因此这个远程桌面解决方案理论上可以在任何支持Java的设备上运行。 2. **网络编程**:实现远程桌面功能的关键是网络通信。开发者可能...
Ray是一个强大的分布式应用程序框架,由RISELab和Anyscale(原名Berkeley ...通过Java API,开发者可以轻松地创建任务和演员,设置资源需求,并保证代码的类型安全,从而在跨语言环境中实现高效的协作和代码复用。
此外,Java的跨平台特性使得基于Java的报表解决方案可以在多种操作系统上无缝运行,增加了其灵活性和适用范围。 ### 报表设计与生成工具 #### JasperReports JasperReports是一款开源的报表工具,它允许开发者...
Java实现工作流的技术方案,为提高业务效率和客户服务体验提供了有效的工具。本文将深入探讨Java如何应用于工作流系统,以及这一技术的优势。 工作流(Workflow)是业务流程在计算机环境中的自动化体现,它涵盖了多...
它支持多种编程语言,包括Java,允许开发者编写可跨多个浏览器和平台运行的测试脚本。Selenium WebDriver是其核心部分,提供了与浏览器进行交互的能力,例如点击按钮、填写表单等。 2. **Java**:Java是一种多平台...
Lodop与Java的结合使用,为实现高效、灵活的打印解决方案提供了一种有效途径,特别是对于条码打印这种需求。以下是对这个主题的详细阐述: Lodop(乐度云打印服务)是一款专业的网页打印控件,它提供了丰富的API...
Ice,全称ZeroC Ice,是一款功能强大的、跨平台的、跨语言的分布式通信框架,它为开发人员提供了一种简单、高效且可靠的解决方案,使得不同操作系统和编程语言之间能够实现无缝的数据交换和通信。Ice的核心理念是...
总之,这个项目展示了跨语言集成的潜力,使得我们可以利用Java的Web开发优势和R的数据处理能力,为用户提供高性能的数据驱动的Web应用。如果你是数据科学家或者Web开发者,这样的组合无疑会增强你的工具箱,帮助你...
1. **Java**:Java是一种跨平台的面向对象编程语言,广泛应用于Web开发。在这个项目中,Java作为后端的主要编程语言,负责处理业务逻辑和数据操作。 2. **Javabean**:Javabean是一种符合特定规范的Java类,通常...
Dubbo通过提供跨语言支持,使得不同语言开发的服务能够相互通信,实现了语言无关性的服务调用。 **Dubbo核心实现** 1. **RPC结构**:RPC(Remote Procedure Call)是一种使程序能够调用另一个远程系统上的方法的...
通过学习《JAVA 数据结构 叶核亚》,读者不仅可以掌握Java语言中的数据结构实现,还能提升自己的算法设计和分析能力,为软件开发打下坚实的基础。书中的源代码、PPT课件和习题解答提供了全面的学习资源,使得自学或...
首先,标题“使用Java生成动态数据的PDF文件”指出我们要利用Java编程语言来创建能够根据动态数据生成PDF的解决方案。Java具有跨平台的特性,使其成为后端开发的理想选择,特别是对于处理数据源和转换任务。 描述中...
【Thrift框架详解】 ...总的来说,Thrift框架提供了一个强大而灵活的工具,能够帮助开发者在异构系统中实现高效的数据交换,简化跨语言服务的开发和维护,是构建分布式系统和微服务架构的理想选择。