翻译至《Practical JMS 第一版》一书的 第一章An Introduction to the JMS 的 第一节Setting the Stage。
-
中间件
随着Internet的发展,为了组织一个灵活、可伸缩的企业应用,分布式计算变得越来越重要。分布式系统意味着系统会分布在不同的机器上,这些机器可能在一个房间,也可以是在遍布全球的不同国家。机器放在需要的地方,分布式系统的不同部分则在放在对系统来说最合适的机器上。创建分布式是一件有挑战的事,想想怎么把一个复杂的应用在单台机器上转起来就知道了。现在再想想,当系统被分解成多个部分装在不同的机器上时,还会引入很多要考虑的问题:比如,不一样的机器架构(如 Intel Vs Alpha)、不一样的OS、不一样的网络带宽,还有说不清楚的网络会失败的因素。 所有这些,作为分布式系统都要考虑进来。一句话就是,分布式应用要远比单机版复杂。
其实分布式系统本身在逻辑上可以至少分成两个部分:实际的业务/功能代码(business/functional code)、基础设施代码(infrastructure/plumbing code)。业务代码是指你真实要完成的功能,和系统是否采用分布式没有关系。与之相对的基础设施代码则和系统是否采用公布式大有关系,如果系统是非分布式的,这部分代码几乎是没有的,而在分布式系统,基础设施代码可能极其复杂,甚至远远比真正的业务代码多的多。基础设施代码要做的事是在系统的不同部分传输数据。怎么传输由基础设施代码的实现决定。
我们注意到,基础设施代码不能完成任务业务上的目标。过程改造上用术语”non−value adding”工作来表示这类代码(不为最终用户提供价值的代码),并推荐要完全剔除这类代码。作为软件开发者,我们知道不可能剔除这类代码,最好的选择是重用这些代码。幸运的是,这些基础设施代码只依赖于系统的分布,而与系统的业务没有关系,重用性很高。软件科学家花了很多时间和精力去开发一个分布式库(比如使用socket)。这样的库需要大量的维护、调试和测试工作,对于软件组织来说,这是一项望而生畏的工作。现在软件社区有了长足发展,出现了很多创建分布式应用的标准,比如:微软的DCOM、SUN的RMI、OMG的CORBA……
上面的讨论的基础设施代码通常称之为中间件(middleware),后文我们也将使用一个术语。总结上文的讨论,中间件可以正式地定义为:
“位于应用和OS之间的一层、在分布式应用之间提供特定服务和互操作性的一系列软件。”
The wide range of software layered between applications and an operating system that provide specialized services and interoperability between distributed applications.
或者,一个简单的说法:中间件是把从一个软件应用连接到另一个软件应用的软件。(middleware is the software used to connect software applications to one another.)
-
中间件的分类
基于中间件在分布式应用之间传输数据的方式,中间件的类型主要分成两大类:
- 基于远程方法调用的中间件,Remote Procedure Call (RPC) based middleware
- 面向消息的中间件,Message−oriented Middleware (MOM)
下面我们深入一些看看这两者。
RPC Based Middleware
可以想一下两个人打电话的情形:一个人说一个听,直到说的人说完了。听的人处理收到的信息,然后回应,处理过程中第一个人要耐心等待。如果你理解这个场景,也就理解了RPC based middleware的要点:使用RPC based middleware的应用传输数据给另一个应用,数据被接收者处理的过程中发送者必须等待(术语称之为堵塞block)。可见,这类中间件,通信(communication)按照锁定的步骤、同步的方式进行,通信双方在通信过程中是紧耦合的。
这类中间件包括Java RMI、OMG的CORBA和Microsoft的DCOM。
万能的MOM?
现在看看风格迥异的另一种中间件,MOM。假设你通过邮局给你的朋友发了一封信。发了信之后,你当然不会等着回信什么也不做,而是继续你的生活。某个时候你收到了回信,但是这时你做事并不会受制于回信。理解了这个情形也理解了MOM工作的机制。MOM前后的想法非常的简单,这给它带来了的威力和流行。 基本上就是说,在分布式系统的任意两个要通信(比如传输数据)的部分(当然是分布了的部分),你安装上第三个”中介”系统。现在系统各个部分向中介发送数据或是从中介接收,而不是之前系统各个部分之间发送或接收数据。这个中介就是MOM。说得更技术一点,我们解耦了两个要互相通信的应用。这被称为”异步通信”。MOM使异步通信成为可能。
还有另一个方面使得MOM对成功的分布式应用更加重要,值得我们注意。如果由于某个原因,不能访问到后一个应用,比如是因为网络原因,或是只是因为应用没有在运行,MOM将负责保持跟踪这些没有成功发送的消息,最有可能的做法是把它们保存在一个队列(Queue)中,之后在可能的时候重新发送这些消息。这就允许使用MOM的分布式系统中的应用有不关联的生命周期。这是非常重要的一点,值得用例子进一步说明一下。
想一下这样一个场景:一个售货员在返回公司办公室的飞机上,正在用他的笔记本电脑填写顾客订单。笔记本没有连到中央电脑上,订单也就不能马上被处理。但是笔记本和中央电脑上都安装了MOM软件。所以即使在订单输入的时候,笔记本不能和中央电脑通信,笔记本上的MOM会跟踪”订单消息”。一旦售货员回到办公室连上局域网,笔记本上的MOM会发送保存的消息到中央电脑的MOM上。中央电脑再接收并处理这些消息。这是MOM为我们提供所要的便利的一个典型例子。MOM会悉心处理,保证消息不会丢失,或是顺序乱了,或是消息有重复。
使用MOM带来的便利和容错性也不完全是免费的午餐,这也会给开发员带来更多的事。一般来说,在多数的情况下,额外的付出是值得的。注意我的说法,是”多数情况下”,而不是所有情况,因为使用哪种类型的中间件是一个和应用和领域相关的问题。比如,如果应用在得到反馈之前什么都不能做,那么基于RPC的中间件更合适。不仅是因为这样做可以降低编程的复杂度,而且避免了和MOM相关的损耗,程序执行得也更好。
PS:
整理过来的内容,2009年8月30日写的。做Napoli项目要用到JMS。