1. 消息传送机制基础
近年来,系统的复杂性和先进性增长非常显著,对于系统的可靠性、可伸缩性和灵活性等的要求要比以前要高。为了适应这种对更好更快的系统日益增长的需求,体系结构师、架构师和开发者已经开始利用消息传送机制,作为解决这些复杂问题的一种方式。
尽管近年来JMS API未发生显著的变化,但消息传送机制的使用方式有了很大的变化。解决可靠性和可伸缩性问题,已经广泛使用了消息传送机制。与此同时,它还被用于解决许多商业应用程序和非商业应用遇到的大量问题。
异构集成是消息传送机制在其中起到关键作用的一个领域,越来越多的公司都正面临着在企业内部、跨企业集成异构系统和应用程序的问题。消息传送机制还具有异步处理请求的能力,它能够为系统体系结构师和开发者提供解决方案,减轻和消除系统瓶颈,提高最终用户的生产率和系统的整体可伸缩性。
应用程序到应用程序之间的消息传送系统,在应用于业务系统时,通常被称为企业消息传送系统,或面向消息的中间件(MOM)。企业消息系统允许两个或更多的应用程序以消息的形式来交换消息,此时,一条消息就是业务数据和网络路由头的一个自包含的数据包,根据其业务场景可以是任何内容。
通过使用面向消息的中间件,消息通过网络从一个应用程序传送到另一个应用程序中,企业中间件产品能够确保消息在应用程序中间正确地分发。此外,对于那些需要可靠地大量交换消息的企业,这些产品能够为其提供容错和负载均衡,可伸缩性和事务型的支持。
所有的企业消息传送系统厂商都为应用程序开发者提供了一个API,用于发送和接收消息。当消息传送系统厂商各自实现自己的网络协议、路由以及管理工具时,提供的开发者语义API是相同的,正是API的这种相似性使得Java消息服务成为可能。
JMS是一种厂商无关的Java API,可以供多个不同的企业消息厂商使用。JMS和JDBC非常相似,应用程序开发者能够重用同样的API来访问不同类型的系统。
1.1 消息传送机制的优点
消息传送机制可以解决诸多的体系结构性挑战,比如异构集成,可伸缩性,系统瓶颈,并发处理,以及整体体系结构灵活性和敏捷性。
1.1.1 异构集成
异构平台的通信和集成可能是消息传送机制最为典型的应用范例,使用消息传送机制可以向在完全不同的平台上实现的应用程序和系统请求调用服务。许多开源消息传送系统和商业消息传送系统使用了一种集成消息桥,能够使用JMS的一条消息转换为通用的内部消息格式,实现Java与其他语言和平台之间的无缝对接。
在应对异构系统的集成问题方面,已经有很多种解决方案。早期的FTP和其他文件传输手段的“人力网络”方法,使用数据库在两个异构系统之间共享信息,远程过程调用RPC,这些解决方案都有各自的优缺点,只有消息传送机制提供的去耦解决方案,能够真正实现跨应用程序或子系统共享数据和功能。Web Service已经作为异构系统集成的另一种可能的解决方案脱颖而出,不过Web Service在可靠性方面的欠缺,使得消息传送机制成为一种更佳的集成选择。
1.1.2 缓解系统瓶颈无论何时,只要您的某个进程跟不上对它访问请求的速度,就会产生系统和应用程序之间的瓶颈问题。在IT系统中,某些组件只能够处理数量有限的请求,而且它很快变成系统瓶颈。IT系统内部,消息传送机制可以用于缓解乃至消除系统瓶颈。与一个同步组件处理众多请求时,众多请求一个接着一个积聚阻塞不同,这时请求会发送到一个消息传送系统,该系统将该请求分发给多个消息侦听器组件。如此一来,就可以缓解单独采用点对点同步连接带来的系统瓶颈,某些情况下可以消除这些瓶颈。
1.1.3 提高可伸缩性和缓解系统瓶颈类似,消息传送机制还可以用于提高系统的整体可伸缩性和吞吐量,同时还能有效地缩减响应时间。通过引入能够并发处理不同消息的多个消息接收者,消息传送系统的伸缩性得以实现。
提高整体可伸缩性的另一种方法,就是要尽可能使用系统的异步方式,如此一来,按照这种方式的组件去耦就会允许系统水平增长。
1.1.4 提高最终用户生产率我们设想这样一种场景:最终用户通过基于Web的用户界面,向系统发送一个请求,这个接口需要花好几分钟执行,在此期间,最终用户一直等待结果,而无法完成其他工作。通过使用异步消息传送机制,最终用户能够向系统发送一个请求,并立即得到响应,表明该请求已经被接收。现在,当执行长时间运行请求时,最终用户可以在系统上继续做其他工作,一旦该请求处理完毕,就立即告知用户,回传处理结果。通过使用消息传送机制,最终用户就能够以更短的等待时间来完成更多的工作,使最终用户能够有更高的生产率。
不过,作为这种灵活性和生产率提升之间的折中平衡,增加了系统的复杂性。
1.1.5 体系结构灵活性和敏捷性使用消息传送机制作为企业体系结构整体方案的一部分,为未来的体系结构灵活性和敏捷性留有更大的空间和余地。这些优良特性是通过使用抽象和去耦来实现的。
体系结构敏捷性是对不断变化的环境快速响应的能力。通过使用消息传送机制来抽象和去耦组件,能够快速地响应软件,硬件,甚至是业务的变化。
1.2 企业消息传送
企业消息传送算不上新概念,消息传送系统,比如商业的IBM MQ, Sonic MQ, msMQ, 以及Tibco Rendezvous等已经存在多年,而Active MQ等几种开源消息传送系统也已经进入市场,并在企业生产环境中使用。此外,面向服务体系架构(SOA)的推出,已经促生了企业服务总线(ESB)的新型消息传送产品。尽管大多数企业服务总线允许使用基于HTTP的通信,基于消息传送的系统仍然继续保持了在大多数生产企业系统当中的标准地位。
企业消息传送的一个关键概念就是:消息是通过网络从一个系统异步地传送给其他系统的,异步传送一条消息意味着发送者不必等待接收者接收或处理该消息;它可以自由地发送消息并持续进行处理。异步消息可以作为独立的自主单元,每条消息都是自包含的,带有处理其业务逻辑所必须的所有数据和状态信息。
异步消息传递机制中,应用程序使用一个简单的API来构建一条消息,将该消息转发给面向消息的中间件,传送给一个或多个预定接收者。消息是自描述的,包含必要的上下文,允许接收者独立地完成它们的工作。
消息传送系统由消息传送客户端和几种消息传送中间件服务器组成,客户端向消息传送服务器发送消息,该服务器随后再将那些消息分发给其他客户端。
1.2.1 集中式体系结构
使用集中式体系结构的企业消息传送系统,依赖于一台消息服务器。消息服务器负责从一个客户端向其他消息传送客户端传送消息。消息服务器可实现发送客户端和其他接收客户端之间的解耦。客户端仅仅能看到消息传送服务器,而不会看到其他客户端,这就允许在不会影响系统整体的情况下添加和删除客户端。
集中式体系结构是一种星形拓扑结构,星形体系结构适合于一个最小数量的网络连接,它仍然允许系统的任何部分和其他部分通信。集中式消息服务器可以是按照逻辑单元方式运行的一个分布式集群。
当前,所有的分散式体系结构都在使用网络层IP组播。基于组播的消息传送系统没有集中式服务器。一些服务器功能(持久性,安全,事务)作为一个客户端的本地部分嵌入进来,而此时消息路由则利用IP组播协议委托给网络层。
与集中式体系结构不同,分布式体系结构不需要用于消息路由的服务器,网络会自动处理路由。然而,每个客户端仍然需要具有像服务器那样的功能,比如消息持久性和仅一次传递之类的消息传送语义。
一个分散式体系结构通常意味着使用IP组播协议,而一个集中式体系结构则意味着TCP/IP在不同组件之间实现的基础。一个消息传送系统厂商的体系结构还可能会将两种方式结合起来,客户端可以使用TCP/IP连接到一个守护进程,它使用IP组播组依次和其他守护进程通信。
1.2.4 以集中式体系结构作为模型本文中使用集中式体系结构作为企业消息传送的逻辑视角。
1.3 消息传送模型
JMS支持两种消息传送模型:点对点(p2p)模型和发布/订阅(pub/sub)模型。发布/订阅模型设计用于一对多消息广播,而点对点模型则设计用于一对一消息传送。
从JMS的视角来看,消息传送客户端成为JMS客户端,而消息传送系统成为JMS提供者。一个JMS应用程序是由多个JMS客户端和一个JMS提供者所组成的业务系统。
生产消息的JMS客户称为消息生产者,而接收消息的客户端称为消息消费者,一个JMS客户端既可以是消息生产者又可以是消息消费者。
1.3.1 点对点模型点对点消息传送模型允许JMS客户端通过队列这个虚拟通道来同步和异步发送、接收消息。传统上,点对点模型是一个基于拉取和轮询的消息传送模型,这种模型从队列中请求消息,而不是自动地将消息推送到客户端。点对点传送模型的一个突出特点是,发送到队列的消息被一个且仅一个接收者接收,即便可能有多个接收者在同一队列中侦听同一消息。
点对点传送模型既支持异步“即用即弃”消息传送方式,又支持同步“请求应答”传送方式。点对点模型比发布/订阅模型具有更强的耦合性,发送者通常会知道消息怎样使用,而且也知道消息被谁接收。
点对点模型支持复杂均衡,允许多个接收者侦听同一队列,并以此来分配负载。JMS提供者负责管理队列,确保每条消息被组内下一个可用的接收者消费一次,且仅一次。JMS规范规定在多个接收者中间分发消息的规则,尽管某些JMS厂商已经选择实现此规则来提升负载均衡能力。
1.3.2 发布/订阅模型发布/订阅模型中,消息会被发布到一个名为主题的虚拟通道中。与点对点模型不同,使用发布/订阅模型发布到一个主题的消息,能够由多个订阅者所接收,有时也称这项技术为广播消息。每个订阅者都会得到这个消息的一个副本。总地来说,发布/订阅消息传送模型基本上是一个基于推送的模型,其中消息自动向消费者广播,无需请求和轮询主题来获得消息。
发布/订阅模型的去耦能力要比p2p模型更强,消息发布者通常不会意识到有多少订阅者或那些订阅者如何处理这些消息。在发布/订阅消息传送模型中,有多种不同类型的订阅者,非持久订阅者是临时订阅类型,只在主动侦听主题时才接收消息;持久订阅者将接收到发布的每条消息的一个副本,即便发布消息时它们处于离线状态。
1.4 JMS API
JMS自身并不是一种消息传送系统;它是消息传送客户端与消息传送系统通信时所需接口和类的一个抽象。与JDBC访问数据库,JNDI抽象访问命令目录接口服务一样,JMS抽象可以访问消息服务提供者,使用JMS,应用程序的消息传送客户端可以实现跨消息服务器产品的移植。
JMS规范是一个具有单向优势的,健壮的规范,包括了一组丰富的消息传送语义,并和简单而灵活的API结合,用于将消息传送合并到应用程序中。
JMS API分成3个部分:公共API,点对点API和发布/订阅API。
公共API中包含的JMS API接口主要有:
l ConnectionFactory
l Destination
l Connection
l Session
l Message
l MessageProducer
l MessageConsumer
这些公共接口中,ConnectionFactory和Destination必须使用JNDI从提供者处获得,其他接口可以在工厂方法在不同的API中创建。
1.4.1 点对点API
点对点消息模型API特指JMS API以内基于队列的接口,而不是公共API接口。
由于基于主题的JMS API类似于基于队列的API。发布/订阅模型使用主题、发布者和订阅者这些术语,而p2p模型使用队列、发送者和接收者。
1.5 实际场景
1.5.1 面向服务体系结构
面向服务体系结构(SOA)作为一种体系结构,定义了从对应的企业服务实现中抽象出来的业务服务,因此,SOA已经促生了一种称为企业服务总线(ESB)的新类型中间件。大多数成熟的ESB产品都使用了消息传送机制,尽管某些ESB产品能够支持传统的非JMS型HTTP传送,但是大多数企业级的产品实现都采用消息传送作为通信协议。
在需要将业务服务从其底层实现中完全抽象出来的SOA内部构建抽象层时,消息传送是一种极好的手段。使用消息传送机制,业务服务无需关心对应的实现处于何种环境。业界对于SOA的热衷和应用,反而又掀起了普遍使用消息传送解决方案的热潮。
1.5.2 事件驱动体系结构事件驱动体系结构作为一种体系结构,建立在下面的前提上:进程和事件编排是动态的和非常复杂的,因而通过一个中央控制组件来进行控制或实现是不可行的。当系统中发生一个活动时,该进程向系统发送一个事件,指示一个活动的发生。这个事件可能会启动其他进程,且进程之间去耦。
消息传送机制是基于事件驱动体系结构系统的基础。通常来说,事件一般是以空负载的消息模式发送的,这些消息会在消息头中包含和事件有关的一些信息,尽管某些消息会将应用程序数据作为事件的一部分进行传送。基于EDA的体系结构大多使用发布/订阅模型,作为在系统内广播事件的手段。
1.5.3 异构平台集成大多数公司经由合并、收购、移植和错误决策后,最终会拥有种类繁多的异构业务支撑平台、产品和语言。消息传送机制在这些异构平台之间的通信中起到了关键的作用。
尽管Java平台可以使用JMS API,而其他平台,比如.NET和C++都无法使用。许多商业消息传送系统厂商和开源消传送系统厂商都会支持JMS API和一个本机API。这些提供者都会有一个内置的消息传送桥,允许JMS提供者将一条JMS消息转换为内部消息,反之亦然。例如ActiveMQ就提供了一个消息传送桥,用于将MSMQ消息转换为JMS格式。
1.5.4 企业应用集成大多数成熟的组织都同时拥有遗留应用系统和新的应用系统,这些系统都是独立实现的,无法实现互操作。很多时候,各个组织都会有将这些应用系统集成起来的强烈需求,以便能够在大规模企业运行中共享信息并实现协作,这些应用系统的集成称为企业应用集成(EAI)。
虽然EAI使用了大量厂商提供的和自己开发的解决方案,但是,企业消息传送系统仍然是大多数解决方案的主流。企业消息传送系统允许烟囱式应用系统和事件进行通信并传送数据,并保持物理上的独立,数据和事件可以通过主题或队列以消息的形式进行交换,它们提供了可以实现各个参与应用系统解耦的一个抽象。
1.5.5 企业到企业XML和现代消息传送系统已经从根本上改变了在如今称为企业到企业的系统中,如何进行业务数据交换和交互的状况。使用消息传送系统是现代B2B解决方案的主流趋势,因为它允许各个组织相互协作,而无需将它们的业务系统紧密集成起来。
1.5.6 地理分散JMS消息传送系统能够确保地理上分散的业务数据交换的安全性和可靠性。
1.5.7 信息广播拍卖网站,股票证券交易这类应用都必须将数据以一对多的方式推送给堪称海量的接收者。广播消息需要各个接收者逐一选择路由和过滤,当输出消息以一对多方式进行发送时,经常需要将对这种消息的响应发回给广播者。这是企业消息传送系统非常适用的一种情况,发布/订阅模型可以用于发布消息,p2p模型可以用于响应。
这种情况下,传送可靠性的选择成为关键因素,需要综合利用消息传送机制的可靠性,因为发布/订阅模型分发速度很快但不可靠,而使用p2p模型是非常可靠的。
1.5.8 构建动态系统
在JMS中,发布/订阅主题和p2p队列是集中管理的,都称为JMS受管对象。应用程序之间通信时,并不用知道各个主题和队列的网络位置,仅仅将主题和队列对象作为标识符使用而已。使用主题和队列为JMS应用程序提供了一定程度位置的透明性和灵活性,使得在一个企业系统中添加和删除参与者称为可能。
1.6 RPC和异步消息传送
RPC是通常用于描述分布式计算模型的术语。基于组件的体系结构,比如EJB就是建立在这个模型基础上的。对于许多应用程序来说,基于RPC的技术已经是,而且将继续是切实可行的解决方案。
1.6.1 紧密耦合的远程过程调用
RPC试图模仿在一个进程中运行的某个系统的行为。在调用一个远程过程时,调用者将被阻塞,直到该过程完成并将控制权返回给调用者。从开发者的角度看,这种同步模型使得该系统就像是运行在一个进程中。RPC同步的本质特性,将客户端和服务器二者紧密地耦合在一起。因为客户端被阻塞,无法继续进行工作,直到服务器做出响应为止。
RPC紧密耦合的本质特性导致出现了相互高度依赖的系统,其中一个系统的失效会对其他系统产生立竿见影的弱化影响。
虽然RPC在多数场景下表现优秀,但在系统对系统的处理过程中,它的同步、紧密耦合特性却是一个严重的缺陷,因为系统对系统有很多垂直的应用程序集成在一起。
这些系统之间的连接管理是多对多的关系,当向混合系统中加入另一个应用程序时,不得不回头来让其他系统都知道它,而且协调应用程序的崩溃,升级问题。
正是RPC系统的同步、紧密耦合、相互依赖等本质特性,使得子系统中出现的故障最终会导致整个系统的失效。
1.6.2 企业消息传送
消息传送机制的一个基本思想就是:规定应用程序之间的通信应该采用异步方式。没有阻塞现象,一旦一条消息被发出,消息传送客户端就能够转向其他任务,不必等待对这条消息的响应。这是消息传送系统和RPC最本质的区别。
在一个异步消息传送系统中,每个子系统都不存在与其他系统之间的耦合。它们通过消息传送服务器进行通信。当某个子系统出现故障,不会妨碍其他子系统的运行。
在网络化系统中会出现故障,这是不可避免的事实。其中的一个系统,会在其连续运行期间的某个时刻,发生不可预测的故障,或需要停机。考虑到这个因素,JMS提供了保证消息传送方式,确保即便发生故障,预定消费者也会接受到这条消息。
保证传送使用的是一种“保存并转发”的机制,这就意味着,如果预定消费者当前并不可用,底层消息服务器就会将输入的消息写到一个持久存储器中。随后,当该接收应用程序变为可用时,保存转发会把预定消费者在不可用时错过的所有消息传送给它们。
JMS不仅仅是另外一种事件服务。它的设计涵盖了范围极广的企业应用程序,包括EAI, B2B和推送模型。通过异步处理,保存转发和保证传送机制,为保持业务连续运行并实现不间断服务提供了很高的可用性。还通过发布/订阅功能和点对点功能,提供了集成灵活性。通过位置透明和管理控制,提供了一种健壮的、基于服务的体系结构。