The principle of message middleware and the introduction of JMS

Summary:

Nowadays, more and more enterprises are faced with various data integration and system integration, and RPC middleware technologies such as CORBA, DCOM, and RMI have also emerged as the times require. However, due to the use of RPC synchronization processing technology, performance, robustness, There are many shortcomings in scalability. The message-based asynchronous processing model adopts the non-blocking calling feature. The sender sends the message to the message server, and the message server forwards the message to the receiver when appropriate; the sending and receiving are asynchronous, and the sender does not need to wait. The life cycle of the sender does not have to be the same, and the sender can indirectly transmit the message to multiple receivers, which greatly improves the performance, scalability and robustness of the program, which makes the asynchronous processing model better than synchronous in distributed applications. Handling models are more attractive. [5]

This article first introduces the principle of message middleware, and then introduces the current popular message middleware products and some open source implementations. Finally, the specification (JMS) proposed by SUN and its partner companies to unify the interfaces of various message middleware systems is analyzed in detail.

Keywords: messaging middleware, JMS, peer-to-peer, publish/subscribe

1. Introduction to middleware

1.1 Definition of middleware

Middleware is a large category of basic software and belongs to the category of reusable software. The middleware is above the operating system software, network and database, and under the application software. [1]

IDC defines middleware as: middleware is an independent system software or service program, distributed application software uses this software to share resources between different technologies, and middleware is positioned on the operating system of the client server. , manage computer resources and network communications.

Therefore, middleware refers to a type of software, which is based on distributed processing software, and its most prominent feature is its network communication function. Middleware can also be considered as common services between platforms and applications, these services have standard program interfaces and protocols. For different operating systems and hardware platforms, there can be multiple implementations that conform to the interface and protocol. [1]

Figure 1.1 Middleware

1.2 Classification of middleware

According to the classification method of IDC, middleware can be divided into six categories: [1]

1) Terminal emulation/screen conversion

2) Data Access Middleware (UDA)

3) Remote Procedure Call Middleware ( RPC )

4) Message Middleware (MOM)

5) Transaction Middleware (TPM)

6) Object middleware

However, in practical applications, middleware is generally divided into two categories: one is the underlying middleware, which is used to support a single application system or solve a class of problems, including transaction middleware, application servers, message middleware, and data access middleware. The other type is high-level middleware, which is more used for system integration, including enterprise application integration middleware, workflow middleware, portal middleware, etc. They usually deal with multiple application systems, in the system level Higher, and mostly run based on the underlying middleware of the former class.

1.2.1 Terminal Emulation/Screen Conversion

This kind of middleware is used to realize the interoperability between the client GUI and the existing server application in the character interface mode. The application and the early mainframe system are rarely used now.

1.2.2 Data Access Middleware

This type of middleware is to establish a mode of interoperability of data application resources and to connect databases or file systems in a heterogeneous environment.

1.2.3 Remote procedure call middleware

This kind of middleware can enable developers to call the process located on the remote server when needed, shielding the communication details in the calling process. An application using RPC to remotely execute a procedure in a different address space has the same effect as executing a local call.

1.2.4 Transaction Middleware

This type of middleware is specially designed for online trading systems. The online trading system needs to deal with a large number of concurrent processes, which involves operating systems, file systems, programming languages, data communications, database systems, system management, and application software. The transaction middleware implements resource management, transaction management and application according to the standard and reference model of distributed transaction processing, which makes it easier to develop applications based on transaction middleware. The transaction middleware is basically only applicable to the online transaction system, and is a relatively specialized middleware.

1.2.5 Message Middleware

This type of middleware refers to the use of efficient and reliable message delivery mechanism for platform-independent data exchange, and the integration of distributed systems based on data communication. It scales interprocess communication in a distributed environment by providing a message passing and message queuing model.

消息中间件可以即支持同步方式,又支持异步方式。异步中间件比同步中间件具有更强的容错性,在系统故障时可以保证消息的正常传输。异步中间件技术又分为两类:广播方式和发布/订阅方式。由于发布/订阅方式可以指定哪种类型的用户可以接受哪种类型的消息,更加有针对性,事实上已成为异步中间件的非正式标准。目前主流的消息中间件产品有IBM的MQSeries,BEA的MessageQ和Sun的JMS[1]。

1.2.6 对象中间件

传统的对象技术通过封装、继承及多态提供了良好的代码重用功能。但这些对象只存在与一个程序中,外界并不知道它们的存在,也无法访问它们。对象中间件提供了一个标准的构建框架,能使不同厂家的软件通过不同的地址空间,网络和操作系统实现交互访问。对象中间件的目标是为软件用户及开发者提供一种应用级的即插即用的互操作性。目前主流的对象中间件有OMG的CORBA,Microsoft 的COM以及IBM的SOM,Sun的RMI

1.3 中间件的特点

一般来讲,中间件具有以下一些特点:满足大量应用的需求,运行于多种硬件和操作系统平台,支持分布式计算,支持标准接口和协议。开发人员通过调用中间件提供的大量API,实现异构环境的通信,从而屏蔽异构系统中复杂的操作系统和网络协议。

由于标准接口对于可移植性和标准协议对于互操作性的重要性,中间件已成为许多标准化工作的主要部分。分布式应用软件借助中间件可以在不同的技术之间共享资源。

总的来说,中间件屏蔽了底层操作系统的复杂性,使程序开发人员面对一个简单而统一的开发环境,减少了程序设计的复杂性,将注意力集中与自己的业务上,不必再为程序在不同软件系统上的移植而重复工作,从而大大减少了技术上的负担。

二、消息中间件原理

面向消息的中间件(MOM),提供了以松散耦合的灵活方式集成应用程序的一种机制。它们提供了基于存储和转发的应用程序之间的异步数据发送,即应用程序彼此不直接通信,而是与作为中介的MOM通信。MOM提供了有保证的消息发送(至少是在尽可能地做到这一点),应用程序开发人员无需了解远程过程调用(PRC)和网络/通信协议的细节。

2.1 消息中间件简介

消息中间件利用高效可靠的消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成。通过提供消息传递和消息排队模型,它可以在分布式环境下扩展进程间的通信。

消息中间件适用于需要可靠的数据传送的分布式环境。采用消息中间件机制的系统中,不同的对象之间通过传递消息来激活对方的事件,完成相应的操作。发送者将消息发送给消息服务器,消息服务器将消息存放在若干队列中,在合适的时候再将消息转发给接收者。消息中间件能在不同平台之间通信,它常被用来屏蔽掉各种平台及协议之间的特性,实现应用程序之间的协同,其优点在于能够在客户和服务器之间提供同步和异步的连接,并且在任何时刻都可以将消息进行传送或者存储转发,这也是它比远程过程调用更进一步的原因。

如下图所示,应用程序A与应用程序B通过使用 MOM 的应用程序编程接口(API)发送消息进行通信。

MOM将消息路由给应用程B,这样消息就可以存在于完全不同的计算机上,MOM 负责处理网络通信。如果网络连接不可用,MOM会存储消息,直到连接变得可用时,再将消息转发给应用程序B。

灵活性的另一方面体现在,当应用程序A发送其消息时,应用程序B甚至可以不处于执行状态。MOM将保留这个消息,直到应用程序B开始执行并试着检索消息为止。这还防止了应用程序A因为等待应用程序B检索消息而出现阻塞。 这种异步通信要求应用程序的设计与现在大多数应用程序不同,不过,对于时间无关或并行处理,它可能是一个极其有用的方法。

2.2 消息中间件与分布式对象调用的比较

分布式对象调用,如CORBA,RMI和DCOM,提供了一种通讯机制,透明地在异构的分布式计算环境中传递对象请求,而这些对象可以位于本地或远程机器。它通过在对象与对象之间提供一种统一的接口,使对象之间的调用和数据共享不再关心对象的位置、实现语言及所驻留的操作系统。这个接口就是面向对象的中间件。

尽管面向对象的中间件是一种很强大的规范被广泛应用,但是面对大规模的复杂分布式系统,这些技术也显示出了局限性:

1.同步通信:客户发出调用后,必须等待服务对象完成处理并返回结果后才能继续执行。

2.客户和服务对象的生命周期紧密耦合:客户进程和服务对象进程都必须正常运行,如果由于服务对象崩溃或网络故障导致客户的请求不可达,客户会接收到异常。

为了解决这些问题,出现了面向消息的中间件,它较好地解决了以上的问题。

消息中间件作为一个中间层软件,它为分布式系统中创建、发送、接收消息提供了一套可靠通用的方法,实现了分布式系统中可靠的、高效的、实时的跨平台数据传输。消息中间件减少了开发跨平台和网络协议软件的复杂性,它屏蔽了不同操作系统和网络协议的具体细节,面对规模和复杂度都越来越高的分布式系统,消息中间件技术显示出了它的优越性:

1.采用异步通信模式:发送消息者可以在发送消息后进行其它的工作,不用等待接收者的回应,而接收者也不必在接到消息后立即对发送者的请求进行处理;

2.客户和服务对象生命周期的松耦合关系:客户进程和服务对象进程不要求都正常运行,如果由于服务对象崩溃或者网络故障导致客户的请求不可达,客户不会接收到异常,消息中间件能保证消息不会丢失。

2.3 消息中间件的传递模式

消息中间件一般有两种传递模型:点对点模型(PTP)和发布-订阅模型(Pub/Sub)[2]。

1. 点对点模型(PTP)

点对点模型用于消息生产者和消息消费者之间点到点的通信。消息生产者将消息发动到由某个名字标识的特定消费者。这个名字实际上对应于消息服务中的一个队列(Queue),在消息传动给消费者之前它被存储在这个队列中。队列可以是持久的,以保证在消息服务出现故障时仍然能够传递消息。

2. 发布-订阅模型(Pub/Sub)

发布-订阅模型用称为主题(topic)的内容分层结构代替了PTP模型中的惟一目的地,发送应用程序发布自己的消息,指出消息描述的是有关分层结构中的一个主题的信息。希望接收这些消息的应用程序订阅了这个主题。订阅包含子主题的分层结构中的主题的订阅者可以接收该主题和其子主题发表的所有消息。

下图展示了发布和订阅模型:[2]

多个应用程序可以就一个主题发布和订阅消息,而应用程序对其他人仍然是匿名的。MOM 起着代理(broker)的作用,将一个主题已发表的消息路由给该主题的所有订阅者。

2.4 消息中间件产品与JMS

从上个世纪90年代初,随着不同厂商消息中间件大量上市,消息中间件技术得到了长足的发展。目前,IBM和BEA的中间件产品在银行、证券、电信等高端行业,以及IT等行业中得到广泛应用。IBM凭借其在1999年推出的应用服务器WebSphere,扎根金融、证券等行业,在超大型以及系统整合型应用方面优势突出;BEA则是专门从事中间件开发的公司,它的应用服务器WebLogic在美国市场占有率超过60%,在国内电信及证券行业占据主要地位;Sun、Oracle、Sybase和Borland等厂商也都有自己的应用服务器;近年来,以金蝶、东方通等公司为代表的国产中间件产品也发展迅速。[3]

由于没有统一的规范和标准,基于消息中间件的应用不可移植,不同的消息中间件也不能互操作,这大大阻碍了消息中间件的发展。 Java Message Service(JMS, Java消息服务)是SUN及其伙伴公司提出的旨在统一各种消息中间件系统接口的规范。它定义了一套通用的接口和相关语义,提供了诸如持久、验证和事务的消息服务,它最主要的目的是允许Java应用程序访问现有的消息中间件。JMS规范没有指定在消息节点间所使用的通讯底层协议,来保证应用开发人员不用与其细节打交道,一个特定的JMS实现可能提供基于TCP/IP、HTTP、UDP或者其它的协议。

目前许多厂商采用并实现了JMS API,现在,JMS产品能够为企业提供一套完整的消息传递功能,下面是一些比较流行的JMS商业软件和开源产品。

1.IBM MQSeries

IBM MQ系列产品提供的服务使得应用程序可以使用消息队列进行相互交流,通过一系列基于Java的API,提供了MQSeries在Java中应用开发的方法。它支持点到点和发布/订阅两种消息模式,在基本消息服务的基础上增加了结构化消息类,通过工作单元提供数据整合等内容。

2.WebLogic

WebLogic是BEA公司实现的基于工业标准的J2EE应用服务器,支持大多数企业级JavaAPI,它完全兼容JMS规范,支持点到点和发布/订阅消息模式,它具有以下一些特点:

1) 通过使用管理控制台设置JMS配置信息;

2) 支持消息的多点广播;

3) 支持持久消息存储的文件和数据库;

4) 支持XML消息,动态创建持久队列和主题。

3.SonicMQ

SonicMQ是Progress公司实现的JMS产品。除了提供基本的消息驱动服务之外,SonicMQ也提供了很多额外的企业级应用开发工具包,它具有以下一些基本特征:

1) 提供JMS规范的完全实现,支持点到点消息模式和发布/订阅消息模式;

2) 支持层次安全管理;

3) 确保消息在Internet上的持久发送;

4) 动态路由构架(DRA)使企业能够通过单个消息服务器动态的交换消息;

5) 支持消息服务器的集群。

4.Active MQ

Active MQ是一个基于Apcache 2.0 licenced发布,开放源码的JMS产品。其特点为:

1) 提供点到点消息模式和发布/订阅消息模式;

2) 支持JBoss、Geronimo等开源应用服务器,支持Spring框架的消息驱动;

3) 新增了一个P2P传输层,可以用于创建可靠的P2P JMS网络连接;

4) 拥有消息持久化、事务、集群支持等JMS基础设施服务。

5.OpenJMS

OpenJMS是一个开源的JMS规范的实现,它包含以下几个特征:

1) 它支持点到点模型和发布/订阅模型;

2) 支持同步与异步消息发送;

3) 可视化管理界面,支持Applet;

4) 能够与Jakarta Tomcat这样的Servlet容器结合;

5) 支持RMI、TCP、HTTP与SSL协议。

三、消息中间件应用之JMS

3.1 JMS简介

Java Message Service 规范 1.1 声称:JMS 是一组接口和相关语义,它定义了 JMS 客户如何访问企业消息产品的功能。

在 JMS 之前,每一家 MOM 厂商都用专有 API 为应用程序提供对其产品的访问,通常可用于许多种语言,其中包括 Java 语言。JMS 通过 MOM 产品为 Java 程序提供了一个发送和接收消息的标准的、便利的方法。用 JMS 编写的程序可以在任何实现 JMS 标准的 MOM 上运行。

JMS 可移植性的关键在于:JMS API 是由 Sun 作为一组接口而提供的。提供了 JMS 功能的产品是通过提供一个实现这些接口的提供者来做到这一点的。开发人员可以通过定义一组消息和一组交换这些消息的客户机应用程序建立 JMS 应用程序。[4]

JMS1.0版本于1998年推出,最新的版本是2002发布的JMS 1.1规范。JMS支持消息中间件的两种传递模式:点到点模式和发布-订阅模式。在JMS 1.1以前的版本中,每一种都有自己的特定于该模式的一组客户机接口。JMS1.1版本提供了单一的一组接口,它允许客户机可以在两个模式中发送和接收消息。这些“模式无关的接口”保留了每一个模式的语义和行为,是实现 JMS 客户机的最好选择。

统一模式的好处是:

1) 使得用于客户机的编程更简单。

2) 队列和主题的操作可以是同一事务的一部分。

3) 为JMS提供者提供了优化其实现的机会。

3.2 JMS体系结构

3.2.1 JMS接口描述

JMS 支持两种消息类型PTP 和Pub/Sub,分别称作:PTP Domain 和Pub/Sub Domain,这两种接口都继承统一的JMS Parent 接口,JMS 主要接口如下所示:

JMS Parent

PTP Domain

Pub/Sub Domain

ConnectionFactory

QueueConnectionFactory

TopicConnectionFactory

Connection

QueueConnection

TopicConnection

Destination

Queue

Topic

Session

QueueSession

TopicSession

MessageProducer

QueueSender

TopicPublisher

MessageConsumer

QueueReceiver

TopicSubscriber

以下是对这些接口的简单描述:

ConnectionFactory:连接工厂,JMS 用它创建连接

Connection:JMS 客户端到JMS Provider 的连接

Destination:消息的目的地

Session:一个发送或接收消息的线程

MessageProducer: 由Session 对象创建的用来发送消息的对象

MessageConsumer: 由Session 对象创建的用来接收消息的对象

3.2.2 JMS消息模型

JMS 消息由以下几部分组成:消息头,属性,消息体。[4]

  • 消息头(header):JMS消息头包含了许多字段,它们是消息发送后由JMS提供者或消息发送者产生,用来表示消息、设置优先权和失效时间等等,并且为消息确定路由。
  • 属性(property):由消息发送者产生,用来添加删除消息头以外的附加信息。
  • 消息体(body):由消息发送者产生,JMS中定义了5种消息体:ByteMessage、MapMessage、ObjectMessage、StreamMessage和TextMessage。

3.3 JMS编程实践

广义上说,一个JMS应用是几个JMS 客户端交换消息,开发JMS客户端应用由以下几步构成:[2]

1) 用JNDI 得到ConnectionFactory对象;

2) 用JNDI 得到目标队列或主题对象,即Destination对象;

3) 用ConnectionFactory创建Connection 对象;

4) 用Connection对象创建一个或多个JMS Session;

5) 用Session 和Destination 创建MessageProducer和MessageConsumer;

6) 通知Connection 开始传递消息。

3.3.1 消息生产者编程

消息生产者程序如下:[2]

package org.jms.test;
import java.io.*;
mport javax.jms.*;
import javax.naming.*;
public class Sender {
    public static void main(String[] args) {
        new Sender().send();
    }
    public void send() {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        try {
            //Prompt for JNDI names
            System.out.println("Enter ConnectionFactory name:");
            String factoryName = reader.readLine();
            System.out.println("Enter Destination name:");
            String destinationName = reader.readLine();
            //Look up administered objects
            InitialContext initContext = new InitialContext();
            ConnectionFactory factory =
                (ConnectionFactory) initContext.lookup(factoryName);
            Destination destination = (Destination) initContext.lookup(destinationName);
            initContext.close();
            //Create JMS objects
            Connection connection = factory.createConnection();
            Session session =
                connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            MessageProducer sender = session.createProducer(queue);
            //Send messages
            String messageText = null;
            while (true) {
                System.out.println("Enter message to send or 'quit':");
                messageText = reader.readLine();
                if ("quit".equals(messageText))
                    break;
                TextMessage message = session.createTextMessage(messageText);
                sender.send(message);
            }
            //Exit
            System.out.println("Exiting...");
            reader.close();
            connection.close();
            System.out.println("Goodbye!");
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }
}

 

3.3.2 消息消费者编程

消息消费者程序如下:[2]

package compute;
import java.io.*;
import javax.jms.*;
import javax.naming.*;
public class Receiver implements MessageListener {
    private boolean stop = false;
    public static void main(String[] args) {
        new Receiver().receive();
    } 
    public void receive() {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        try {
            //Prompt for JNDI names
            System.out.println("Enter ConnectionFactory name:");
            String factoryName = reader.readLine();
            System.out.println("Enter Destination name:");
            String destinationName = reader.readLine();
            reader.close();
            //Look up administered objects
            InitialContext initContext = new InitialContext();
            ConnectionFactory factory =
                (ConnectionFactory) initContext.lookup(factoryName);
            Destination destination = (Destination) initContext.lookup(destinationName);
            initContext.close();
            //Create JMS objects
            Connection connection = factory.createConnection();
            Session session =
                connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            MessageConsumer receiver = session.createConsumer(queue);
            receiver.setMessageListener(this);
            connection.start();
            //Wait for stop
            while (!stop) {
                Thread.sleep(1000);
            }
            //Exit
            System.out.println("Exiting...");
            connection.close();
            System.out.println("Goodbye!");
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }
    public void onMessage(Message message) {
        try {
            String msgText = ((TextMessage) message).getText();
            System.out.println(msgText);
            if ("stop".equals(msgText))
                stop = true;
        } catch (JMSException e) {
            e.printStackTrace();
            stop = true;
        }
    }
}

 

以上程序都较为简单,基本上为自解释的。

四、消息中间件总结

消息中间件自从产生以来发展迅速,在分布式联机事务处理环境中,它担当通讯资源管理器(CRM)的角色,为分布式应用提供实时、高效、可靠的、跨越不同操作系统、不同网络的消息传递服务,同时消息中间件减少了开发跨平台应用程序的复杂性。在要求可靠传输的系统中可以利用消息中间件作为一个通讯平台,向应用提供可靠传输功能来传递消息和文件。

参考文献

[1] 李华琰、郭英奎 著:Java 中间件开发技术 . 中国水利水电出版社,2005

[2] JMS在线教程 . 2004 http://www6.software.ibm.com/developerworks/cn/education/java/j-jms

[3] 基于JMS的消息中间件的研究和设计 . 姚刚. 2006

[4] 消息中间件和JMS . 2005. http://www.huihoo.org/jfox/jfoxmq/mom_jms.html

[5] 基于JMS的数据汇集系统的研究与实现. 2006.

http://www.cndw.com/tech/program/2006042760285.asp

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326775494&siteId=291194637