深入探讨SOAP、RPC和RMI
在 Brett McLaughlin 关于Soapbox的第二回合中,他详细地将“简单对象访问协议”与 RMI 和 RPC 进行了比较,并就开发人员如何在这三种消息协议中做出最佳选择而提出建议。他查看了来自 IBM 和微软的现实世界 SOAP 实现,并检查了 XML 的局限性 - SOAP 的基本编码格式 - 和作为全功能编程语言所涉及的问题。本文包含 RPC 和 SOAP 机票请求的样本代码,用于并排比较。
自从上一次谈论临时讲台以来,围绕 SOAP 的大量宣传仍在继续升温,毫不奇怪。微软在其 .NET 平台中称赞该协议,Apache 声称它是消息传递(至少在我碰到的 XML 圈子中)最要紧的事, 并且每个人都希望获得它。在 Enhydra 和 jBoss(两种流行的开放源码应用服务器)以及许多商业应用服务器公司,正在开发用于 SOAP 的服务。那么,自从上一篇文章以来,SOAP 故事有哪些变化呢?老实说,几乎没有。SOAP 就如同一块已经获得了动量准备滚下山去的巨石。问题是您是否正在跟随着它跑,或站在它下面仰面看着它,希望它不会超过您。我将去除所有市场广告,并给您一些工具来明确评估 SOAP 是否适合于您。换句话说,我将帮助您,确保不会被那块巨石压碎!
本文接着我上一篇临时讲台,那篇文章深入探讨了 SOAP,特别是它在 RPC 和 XML-RPC 方面的基础。 这里,我将 SOAP 与 Java 空间中通信方面,它最大的竞争对手 RMI(远程方法调用)进行比较。RMI 用在 Java 中跨越网络的组件间的通信上,已有很长时间了,随着在如 Enterprise JavaBeans (EJB) 技术中使用该技术,它继续流行。我将研究 RMI 与 SOAP 如何不同 - 包括 SOAP 的现实和 SOAP 的未来展望。最后,我将看一下我称做的“工作级 SOAP”,这指您现在可以从 微软和 IBM 下载。本文这部分将从概念性转向开发人员正在询问的实际问题的具体考虑:“现在,SOAP 马上能为我做什么?”
RMI 还是 RPC?
在这一两部分系列的第一篇文章中,我研究了 SOAP,确切描述了它是什么,以及同样重要的,它不是什么。特别是,我查看了 RPC、XML-RPC 和 SOAP,剖析了每项技术所包含的。您也许奇怪地发现许多 SOAP 的“特性”,实际上是 XML-RPC 的特性,不是 SOAP 固有的。 也许您还了解到可以用更简单的包而不是 SOAP 来满足商业需求,如在 Userland XML-RPC 站点(请参阅参考资料)上找到的 XML-RPC 库之一。或者,您可能决定,利用 SOAP 的封装机制,可以方便地编码应用程序特定的数据类型,SOAP 确实是您所需的。在任何情况下,有了我在第一篇临时讲台文章中提供的信息,您应该拥有了足够的 SOAP 和 RPC 知识,可以与今天编程中它的主要对手 RMI 做比较。有许多好的理由要使用 RMI 而不用 RPC,但同样也有好的理由使用 RPC 而不用 RMI。(难道总是这种情况?)在以下的章节中,讨论了在这三种选项:SOAP、RPC 或 RMI 之间作出选择所必需的主要因素。
它取决于语言
使用 SOAP、RPC 还是 RMI 的决定将根据您使用的编程语言。如果您是 Java 程序员, 正好有 作为 Java API 一部分的 RMI -并且它易于上手而且有编制良好的文档。 如果不是 Java 程序员,则 RMI 不是自动的选项。事实上, 非 Java 程序员会发现 SOAP 是极吸引人的解决方案,甚至对 Java 开发人员也是如此。SOAP 提供了比 CORBA 和其它远程协议更容易的消息传递和通信方式。 而且,它为 XML 提供的编码也是非常便利的:虽然有一些 C 和 Perl XML 语法分析器可用,通常 这要比 Java 在同样条件下更慢一些(在开发方面)。 所以,SOAP 不但将消息传递添加到您的工具箱,而且还去除了必须用工具来对 XML 进行语法分析的负担,并且该工具没有如其 Java 搭档一样成熟。
实际上,使用 SOAP 的大多数是 Java 程序员,所以又回到了原来的问题,使用 RPC 还是使用 RMI。 如果您是 Java 开发人员,并且必须要与非 Java 应用程序或组件进行通信,将会怎么样?您的应用程序空间的其它参与者可能不能发送或接收 RMI 通信。可能安全地说法是他们不希望处理 IIOP 或 CORBA 之间的争论。但是他们确实能收到 SOAP 交付的友好的、简单的有效负载。译码有效负载和以某种方式(使用 SOAP API 他们自己的语言)响应使通信能简单地跨越“编程语言障碍” - 并且这使 SOAP 具有吸引力。
对于作为开发人员的您,这意味着什么呢?如果您用 Java 编码,与 Java 交谈,除了 Java,从来不需要其它任何事,那么 SOAP 丧失了一些吸引力; 这时,开发人员接受 RMI 要多于 SOAP,并且更易于学习和使用。然而,对于真正的亲 Java 者,SOAP 仍然有一些有利条件(我将在后面谈到),它只是没有那么吸引人了。如果不在 Java 环境下工作,或者需要与非 Java 环境通信,那么 SOAP 开始发光。它使用 XML,这是与厂商和语言无关的, 并且易于使用 Perl、C、Ada 甚至是 COBOL(虽然为何使用 COBOL 是另一场演说的主题)进行语法分析。SOAP 是对如 CORBA 和 RMI-IIOP 这样的重型范例吸引人的替代。并且,由于现在 SOAP 是一项深受欢迎的技术,其它那些语言的 SOAP API 很快会到来。在这些情况下,可以认为 SOAP 是消息传递真正的朋友。当然,SOAP 不仅仅是消息传递还有更多,现在,我将演示客户机如何与 SOAP 交互,以及如何与 RMI 交互。
调用 vs 请求和响应
在决定是否用 RMI 而不用 RPC 或者反之亦然时,看一下这两者采用的交互方式是重要的。 交互的 RMI 模型与 RPC 中使用的是完全不同的:在如何操作远程对象方面有显著的不同。事实上,在 RPC 和 SOAP 中,根本不直接操作远程对象!为了阐明这一点,我将深入探讨该模型。
在 RMI 中,远程对象按照好象它是本地行事。客户机应用程序直接调用远程对象存根上的方法。通过 RMI 和 Java 的魔力,该存根使可以跨越网络编码方法调用,并且最终结果是,使另一台机器上的对象调用了一个方法。然后,结果类似地编码,并返回给存根,该存根将结果返回。对客户机来说,它似乎没有涉及远程对象。也许用这种交互方式的最大好处是类型安全以及直接使用方法名是可能的。换句话说,遵循了正常 Java 约定:调用了一个方法,如果参数不正确,则发生编译时错误。然而,我必须告诉您,该方法有不利方面。许多异常最终是包装在 java.rmi.RemoteException 中。所以,您必须确保在调用 RMI 对象的应用程序中有一些知识,否则您会丢失在 RemoteException (可能 NumberFormatException)中的包装信息。结果是缺乏关于出错的信息。
替代物 RPC 风格的调用遵循完全不同的道路。与其涉及正在调用的方法,倒不如有要发送的消息,基本上是对远程服务器的请求。然后,明确表达响应,并返回响应。在这种情况,客户机从来不直接调用方法。请求通常由调用远程服务器上的方法名称和参数组成。然而,这些全部是编码的。清单 1 显示了代码片段,请求预定和购买机票。
现在,我知道您可能有一种被欺骗的感觉,因为本文是关于 SOAP 的文章,而您正在获取 XML-RPC 代码样本。为了完整性缘故,请查看清单 2 中使用 SOAP 的相同调用。
到现在,与 RMI 相比,使用 XML-RPC 还是使用 SOAP 都无关紧要;XML-RPC 与 SOAP 中客户机与服务器之间的交互是一样的,而且这两者与 RMI 有巨大的区别。在这些清单中所看见的方法名和参数是以 String 或 Parameter 编码的(取决于所使用的技术)。您还看到查找必须按名称进行 - 而不是通过获取 Java 虚拟机中实际 java.lang.reflect.Method 的句柄,如 RMI 中一样。使用这种 RPC 编码风格可能有更多事物出错:服务器上的方法可能丢失,或者客户机上的方法可能拼错。其它可能遇到的问题是自变量类型不正确,指定的自变量名称不正确;或者服务器当机。用 RPC,所有这些问题都是运行时问题,而用 RMI (除了服务器当机)这些问题可能是编译时问题。通常,最好在编译时间捕获问题而不是在运行时。问题是使用 RPC 或 SOAP 使您失去了 Java 编译器的大量便利。
RPC 风格确实提供了一些有利之处。首先,它允许客户机与服务器之间有更大的独立性。不象 RMI,无需生成存根类并将它们传递给客户机。服务器无需让客户机知道,就可以完全关机和被替换。(在 RMI 中,可以做到这一点,但实现起来要困难得多。)事实上,没有中断客户机处理,可以在调用间升级和重新编译服务器上的类和方法。并且使用 SOAP(与 XML-RPC 单独对比),可以用 SOAP 的故障机制,API 的标准部分,来转播客户机可能发生问题的大量信息。
再一次。我让您根据工作中 RMI、RPC 和 SOAP 的使用来做出判断。在某些情况下,SOAP 有明显的优越性:它非常适合异步通信和针对松耦合的客户机和服务器。但这种好处会招致一些不利结果。必须做大量的运行时检查,而且开发人员丧失了许多可以确保方法和参数是正确的编译时便利。如果您已经读过我的关于临时讲台的第一篇文章,那么我确信您知道我想说的:评估您的商业需求。去芜存箐。您很可能会发现,在某些情况下,发出 SOAP 调用,然后让远程服务器平静地处理任务非常管用;在其它情况下,希望使用 RMI 来进行 Java 到 Java 的通信以及为确保编译时的类型安全。
工作级 SOAP
我已经将 SOAP 与 RPC、XML-RPC 和 RMI 作了比较,研究了它们之间的不同以及优点和缺点。现在还不是结束的时候;我还需要考虑一些关于 SOAP 自身的问题。到目前为止,关于 SOAP 的讨论是集中在 技术的“概念性实现”;我已经演示了如果按 "as is" 来实现规范,那么 API 行为如何。在现实中,没有所谓的完美实现。记住,工具箱是由人开发的!记住,在下一节中,我查看了实际的 SOAP 实现 - “工作级 SOAP”是什么样子,以查看如何,以及如果,交付 SOAP 的许诺。
实践 vs 展望:IBM 和 Microsoft 的 SOAP
实现和规范如何相互符合呢?两个主要的 SOAP 实现在开发中,一个来自 Apache, 作为 IBM Apache XML 项目的一部分,一个来自微软,作为它的 .NET 平台的一部分。在这两种情况下,在公开发行方面都不到一年的时间,带来了实现的成熟性问题。
也许来自 Apache XML 最期望的发行版,Apache SOAP 工作,是 IBM 原来在 SOAP4J 上工作的延伸。给予 Apache 的 SOAP 版本号是 "2.0",很难与许多其它 2.0 的产品相提并论,那些产品通常是很健壮。规范包含大量还未添加到 SOAP 2.0 的项;然而,在大多数应用中不需要这些中的大部分。其不利之处是为了符合规范必须支持这些少数的、不经常使用的项。直到实现它们,您才会使用它们,SOAP 工具箱也许没有进行性能调整,因为工作仍然在特性上进行。遗憾的是,您为那些不常用的特性付出了代价。
微软的 SOAP 实现,.NET 平台的核心部分,在 SOAP 的功能和符合方面,几乎提交到 W3C 的 SOAP 一致。这将极有可能继续成为真的,由于 SOAP 是大多数通信将在 .NET 平台中出现的方法。 组件之间通过 SOAP 互相通信的能力 -在开发和生产中 - 是 .NET 的主要特征之一,所以不要展望微软的 SOAP 实现会动摇。同时,您也应该展望许多专有特性做到微软实现中。有了这些“钩子”,微软驱动的产品将能够利用特定于 .NET 平台的捷径。如果您正在使用微软的全部产品,这些钩子会很有用处;然而,如果您正在尝试用普通的 SOAP 实现,要注意了!
底线是 SOAP 还处于在快速发展阶段,并且今天的 SOAP 并不完全是未来许诺的 SOAP:来自 IBM 和微软的 SOAP 实现仍然正在开发和完成。不要期望现在开始使用 SOAP(通过这些项目之一)并在几个月内能够无缝地升级至新版本;特性会改变,功能性会改变,随之会产生一些混乱,通常会导致对应用的其余部分的修改。 另外,如果 W3C 将 SOAP 作为一种新规范接受,在最终建议书交付之前,会有几个修订版。这些修订版会导致 SOAP 实现的额外变更,这当然意味着对您的开发环境进行更多升级。
总之,对于目前的 SOAP 实现,它还有很多路要走。如果您没有陷入到实现细节中,并且当升级版出现时愿意有灵活性,那么可以从使用 IBM 和微软的现在 SOAP 实现中学到许多。可以调查 RPC 是如何工作的,远程方法如何定位,以及 SOAP 信封和故障机制行为。换句话说,当 SOAP 的完整和稳定的实现确实到来时,您可以很好地走在这项竞赛的前面。
关于 XML 的说明:您全部所需?
关于 SOAP 供应商,最终的警告是:不要在 XML 上下赌注。我确信我错误地引用了这句话,所以听我把话说完。XML 还在这里。但 XML 最适合于较大的应用程序环境,用真正的编程语言,如 Java 来支持它。 有一些人说,“XML 足够了。”随着实际应用领域中增添了如 SOAP、XML-RPC、 RSS (RDF Site Summary) 和其它 XML 词汇,人们正提倡将 XML 本身作为一种编程语言。使用 Apache Cocoon、XSL、XSLT、SOAP 和一种 XML 数据库, 使人们相信不用编写一行 Java 代码,仍然能够运行整个应用程序。(公平而言,在 Cocoon 中实际没有人建议这么做;它只是一个示例。)
这前提仅仅 XML 需要,而该前提本质上是有缺陷的。 使用 XML 要有代价:与二进制格式相比,编码要花费更长时间,而且经过网络发送时,它更大些。XML 的好处是它可以跨编程语言和跨平台理解。但是如果您不需要这种全面的功能,那么 XML 就没有多大意义了!例如,在同一个应用程序中的 servlet 和 EJB 之间使用 XML 就是一个坏想法。这需要花时间来处理 XML 和花资源来传输 XML,并且什么也得不到。
SOAP 是工具。它应该只作为工具使用,帮助应用程序进行消息传递和数据表示。这些应用程序需要的不只是 XML。我可以理解某些人提倡不要被 Java 所束缚 - 尤其当 Sun 已经显示不愿意为该语言创建开放标准过程 -尝试简单地用 XML 作为 Java 的替代物是不切实际的。所以,把 SOAP 和 XML 作为工具箱中的更多工具。虽然它是多功能的、功能极其强大的工具,但它仍然只是一件工具。
结束语
在这一两部分的文章中,我研究了备受瞩目的 SOAP。我对它进行了剖析,把它作为与其先辈 RPC 和 XML-RPC 进行了对比,并且将它与其主要竟争对手 RMI 进行了比较。我还查看了可用的 SOAP 实现对比 W3C 的实际 SOAP 说明)。即使您还未对 SOAP 做出决定,在这一点上,您应该能够认识到其优点和其问题。
我希望您开始形成您自己的关于 SOAP 状态的观点。如果等待某种命令来告诉您 SOAP 是否是 “好的”还是“坏的”,那么这是不会发生的。坦白的说,我不能告诉您是否您应该使用 SOAP。但我可以告诉您,今天在许多情况下,开发人员正在使用 SOAP,而改用 XML-RPC 的话,可能是足够和易于编程的。除此以外,XML-RPC 库要比 SOAP 库成熟得多。与此同时,某些程序员每天挣扎于 Perl 和 C 组件、C 和 Java 组件之间的通信。这些开发人员可以从转向基于 SOAP 或基于 XML-RPC 的通信模型中获益匪浅。另一方面,从不转向 Java 以外语言的 Java 开发人员可以转向 RMI 而不是使用 SOAP,他们会看到极大的性能改善。
我将留给您我重复多次的基本建议:“去芜存箐”。在您对 SOAP 感到太兴奋之前,要确保它符合您的商业需求。如果它不符合,不要害怕技术性“当前”比同仁要少;对有简单的、成功的应用程序的满意远远超过为了在应用程序中使用最时髦的技术而使用如 SOAP 这样的技术引起的麻烦。无论怎样,关注 developerWorks XML 专区,因为我会紧密监控和涵盖与 SOAP 相关的任何新开发。而其他开发人员会轮流站上临时讲台。
参考资料
通过单击本文顶部或底部的讨论,可以参加本文的论坛。
通过阅读 W3C 的说明:SOAP 1.1 Note?来专心致志于 SOAP。
在?xml.apache.org?上获取从 XML Apache 的实现。
在?MS SOAP SDK vs IBM SOAP4J?和?MS SOAP SDK vs. IBM/Apache XML-SOAP?这两篇文章中,将 IBM 的 SOAP 实现与微软的 SOAP 实现做了比较。
在 Userland?XML-RPC 网站了解关于 XML-RPC 的内幕,其中您可以发现几个 XML-RPC 库。
请阅读 Brett 所著的?Java and XML?一书中更多有关 XML 和相关技术。
关于?IBM 的 SOAP 安全性扩展页面描述了把安全性保卫措施添加到 SOAP 实现中的建议(包括至 Note to the W3C 的链接), 以及一个带扩展的?SOAP Envelope API。
IBM 的?Web 服务实情表简要说明了 SOAP 如何符合 Web 服务倡议,并提供了其它资源链接。
在伦敦举行的 IBM Solution 2001 开发人员大会上,2001 年 5 月 17 日星期四的会议上提到了 SOAP、Web 服务和 MQSeries 系列。