JMS/ Geeting Started with Java Message Service

丁寧で易しい!

【*】イントロ
Remote procedure call (RPC) systems, including Java RMI, are synchronous -- the caller must block and wait until the called method completes execution, and thus offer no potential for developing loosely coupled enterprise applications w/o the use of multiple threads. In other word, RPC systems require the client and the server to be available at the same time. However, such tight coupling may not be possible or desired in some applications.
Message-Oriented Middleware (MOM) systems provide solutions to such problems. They are based on the asynchronous interaction model, and privide the abstraction of a message queue that van be accessed across a network.

RMI等のRPCは同期前提。
呼び出し側が、呼ばれたメソッドの完了を待たないとダメ。
つまり、マルチスレッドなアプリは望み薄。
で、登場するのがJMS
非同期前提。

The Java Message Service (JMS), which is designed under the Java Community Process as JSR914, is the first enterprise messaging API that has received wide industry support. the Java Message Service (JMS) was designed to make it easy to develop business applications that asynchronously send and receive business data and events. it defines a common enterprise messaging API that is designed to be easily and efficiently supported by a wide range of enterprise messaging products. JMS supports both messaging models: point-to-point (queuing) and publish-subscribe.

JMSの送受信モデルは2つ。
PTP(キュー使用)とPub/Sub。

JMS was defined to allow Java application to use enterprise messaging systems. More importantly, it provides a common way for Java applications to access such enterprise messaging systems. JMS falls under middleware, and specifically Message-Oriented Middleware (MOM), which is a relatively low-level of abstraction that runs underneath complementary layers such as database and application adapters, event processing, and business process automation.

JMS defines a set of interfaces and sematics that allow Java applications to communicate with other messaging implementations. A JMSimplementation is known as a JMS provider.

JMSは、インタフェースやらを定義した仕様。
プロバイダと呼ばれる実装部分はベンダーがサポートするもの。


【*】Architecture
A JMS application is composed of the following parts:
- A JMS provider: A messaging system that implements the JMS specification.
-JMS clients: Java applications that send and receive messages.
-Messages: Objects that are used to communicate information b/w JMS clients.
-Administered objects: Preconfigured JMS objects that are created by an administrator for the use of JMS clients.


【*】Message Delivery Models
JMS supports two different message delivery models:
1. Point-to-Point (Queue destination):
in this model, a message is delivered from a producer to one consumer. the Messages are deliveredd to the destination, which is a queue, and then delivered to one of the consumers registered for the queue. While any number of producers can send messages to the queue, each messages is guarateed to be delivered, and consumed by one consumer. If no consumers are registered to consume the messages, the queue holds then until a consumer registers to consume them.

PTPは、(送信側)いっぱい 対 (受信側)いっぱいのうちのどれか1つ。
送信側はメッセージ投げてんけど、受信先が1つも登録されていない場合、
受信先が現れるまでキューがメッセージを保持してる。

2. Publish/Subscribe (Topic destination):
In this model, a message is delivered from a producer to any number of consumers. Messages are delivered to the topic destination, and then to all active consumers who have subscribed to the topic. In addition, any number of producers and send messages to topic destination, and each message can be delibered to any number of subscribers. If there are no consumers registered, the topic destination doesnt hold messages unless it has durable subscription for inactive consumers. A durable subscription represents a consumer registered with the topic destination that can be inactive at the time the messages are sent to the topic.

Pub/Subは、(送信側)いっぱい 対 (受信側)そのトピックを購読登録している全部。


【*】The JMS Programming Model
A JMS application consists of a set of application-defined messages and a set of clients that exchange them. JMS cients interact by sending and receiving messages using the JMS API.
A message is composed of three parts: header, properties, and a body.
+ The header, which is required for every message, contains information that is used for routing and identifying messages. Some of these fields are set automatically, by the JMS provider, suring producing and delivering a message, and others are set by the client on a message by message basis.
+ Properties, which are optional, provide values that clients can use to filter messages. They provide additional information about the data, such as which process created it, the time it was created. Properties can be considered as an extension to the header, and consist of property name/value pairs.
+ The body, which is also aoptional, contains the actual data to be exchaged.
The JMS specification defined six type or classes of messages that a JMS provider must support:
- Message: This represents a message w/o a message body.
- StreamMessage: A message whose body contains a stream of Java primitive types. It is written and read sequentially.
- MapMessage: A message whose body contains a set of name/value pairs. The order of entries is not defined.
- TextMessage: A message whose body contains a Java string... such as an XML message.
- ObjectMessage: A message whose body contains a serialized Java object.
- BytesMessage: A message whose body contains a stream of uninterpreted bytes.

【*】Producing and Consuming Messages
Here are the necessary steps to develop clients to produce and consumer messages.

[Connection Factory] creates [Connection]
[Connection] creates [Session]
[Session] creates [Message Producer], [Message Consumer] and [Message]
[Message Producer] sends to [Destination]
[Message Consumer] receives from [Destination]


【*】Client to Produce Messages
1.
User the Java Naming and Directory Interface (JNDI) to find a ConnectionFactory object, or instantiate a ConnectionFactory object directly and set its attributes.
A client uses a connection factory, which is an instance of either QueueConnectionFactory (point-to-point) or TopicConnectionFactory (publish/subscribe), to create a connection to a provider.
--------------------
Context ctx = new InitialContext();
ConnectionFactory cf1 = (ConnectionFactory) ctx.lookup("jms/QueueConnectionFactory");
ConnectionFactory cf2 = (ConnectionFactory) ctx.lookup("/jms/TopicConnectionFactory");
--------------------
Alternatively, you can directly instantiate a connection factory as follows:
--------------------
ConnectionFactory connFactory = new com.sun.messaging.ConnectionFactory();
--------------------
2.
User the ConnectionFactory object to create a Connection object. this can be done as follows:
--------------------
Connection connection = connFactory.createConnection();
--------------------
Note that you must close all connections you have created. This is done using the Connection.close() method.
3.
Use the Connection object to create one or more Session objects, which provide transactional context with which to group a set of sends and receives into an atomic unit of work. A session can be created as folows:
--------------------
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE)
--------------------
The createSession() method takes two arguments: the first means that the session is not transacted, and second means that the session will automatically acknowledge messages when they have been received successfully.
4.
Use JNDI to find Destination object(s), or instantiate one directly and configure it by setting its attributes.
A destination object is used by the client to specify the source of messages it consumes and the target of messages it produces. In the point-to-point messaging, destinations are known as queues, and in the publish/subscribe model of messaging, they are known as topics.
you can lookup the JNDI of a queue named jms/SomeQueue as follows:
--------------------
Destination dest = (Queue) ctx.lookup("jms/SomeQueue");
--------------------
or, you can directly instantiate and configure a destination object as follows:
--------------------
Queue q = new com.sun.messaging.Queue("world");
--------------------
5.
Use a Session and a Destination object to create the needed MessageProducer object, which are used for sending messages to destination. The code below shows how that is done.
Note that you can create a MessageProducer object w/o specifying a Destination object, but in that case a Destination object must be specified for each message produced
--------------------
MessageProducer producer = session.createProducer(SomeQueue OR SomeTopic);
--------------------
Once a producer has been created, it can be used to send messages as follows:
--------------------
producer.send(message);
--------------------


【*】Client to Consume Messages
The first four steps are the same as above.
5.
Use a Session object and a Destination object to create any needed MessageConsumer objects that are used for receiving messages. This can be done as follows:
--------------------
MessageConsumer consumer = session.createConsumer(SomeQueue or SomeTopic);
--------------------
Note that if topic is being used, then you can use the Session.createDurableSubscriber() to durable topic subscriber.
Once the consumer has been created, it can be used to receive messages. Message delivery, however, doesnt begin until you start the connection created eariler, which can be done by calling the start() method:
--------------------
connection.start();
Message msg = consumer.receive();
--------------------
A long parameter can be passed to the receive() method to specify a time-out(ex, 3000L for 3 seconds).
It is important to note that the receive() method is used to consume a message synchronously. In order to consume a message asynchronously, a message listener is used.
6.
If asynchronous communication desired, instantiate a MessageListener object and register it with a MessageConsumer object.
A MessageListener object acts as an asynchronous event handler for messages. The MessageListener interface contains one method, onMessage(), which you implement to receive and process the messages.
In the following snippet of code, the class MyListener implements the MessageListener interface. The message listener is registered with a specific cunsumer using the setMessageListener():
--------------------
MessageListener listener = new My Listener();
consumer.setMessageListener(listener);
--------------------
In order to avoid missing messages, the start() method should be called on the connection after the listener has been regstered. When message delivery begins, the JMS provides automatically invokes the message listener's onMessage() whenever a message is delivered.
7.
Instruct the Connection object to start delivery of messages by calling the start() method.


【*】Sun java System Message Queue 3.5
Sun is one of the principal designers of JMS, and therefore they have been shipping a production implementaion of JMS since 1999.

The Sun Java System Message Queue is a currently shipping produc, which acts as one system for all business messaging needs through support for point-to-point and publish/subscribe messaging models as well as support for synchronous and asynchronous messaging.

Using this product, processes running on different platforms and operating systems can connect to a common Message Queue service to send and receiver information.
Application developers can focus on the business logic of thrie applications rather than the low-level details of how to achieve or implement reliable communication across the network.

This product is a leading business integration enterprise message server that provides a standards-based messaging solution. It is available in two edition: Platform Edition and Enterprise Edition.

-The pratform Edition is both the reference implementation of JMS 1.1 specification as well as product. It is designed for small-scale deployments and development environments. The Platform Edition is included in the J2EE 1.4 reference implementation, and the Sun Java System Application Server Platform Edition 8.
-The Enterprise Edition is a high performance messaging system designed for large-scale enterprise deployments for integrating disparate applications. It includes key enterprise features such as scalability, reliability, and advanced security.

It is worth nothing that the product includes a J2EE 1.4 compliant Resource Adapter that ebables you to use Sun Java System Message Queue as JMS provider for any J2EE 1.4 technology-compliant application server. This enables businesses to maximize their investments in current IT assets by being able to continue using their existing application server, but leverage the benefits of Sun Java System Message Queue.


【*】Synchronous and Asynchronous Message Consumption
A JMS client can consume messages either synchronously or asynchronously.
-Synchronous:
In this mode, a client receives a message by invoking the receive() method of the MessageConsumer object. The application thread blocks until the method returns, and this has the consequence that if a message is not available, it blocks until a message becomes available or the receive() method times out. Also, note that in this model the client can consume one message at a time.
-Asynchronous:
In this mode, the client registers a MessageListener object with a message consumer. This is like a call-back where the client consumes a message when the session invokes the onMessage() method. In other words, the application's method doesn't block.


【*】Reliable Messaging
JMS defines two delivery modes:
1. Persistent messages: Guaranteed to be successfully consumed once and only once. Messages are not lost.
2. Non-persistent messages: Guaranteed to be delivered at most once. Message loss is not a concern.
This, however, is all about performance trade-offs. The more reliable the delivery of messages, the more bandwidth and overhead required to achieve that reliability. Performance can be maximized by producing non-persistent messages, or you can maximize the reliability by producing persisten messages.

For more information on using such advanced feathres, please see Chapter 3 of the J2EE 1.4 Tutorial.
http://java.sun.com/j2ee/1.4/docs/tutorial/doc/index.html


【*】Message-Driven Beans
JMS is a mandatory API and service in J2EE platform. A good example is the message-driven bean, one of a family of EJBs specified in EJB 2.0/2.1. The other two EJBs are session beans and entity beans, which can only be called synchronously.

A JMS Message-Driven Bean (MDB) message consumer that implements the JMS MessageListener interface. The onMessage() method is invoked when a message is received by the MDB container. Note that you do not invoke remote methods on MDBs (like with other enterprise beans) and as a result there are no home or remote interfaces associated with them. It also worth nothing that with J2EE 1.4, MDBs are not limited to JMS; rather, a multiplicity of MDB interfaces can be declared and consumed by application components implementing those interfaces.



ref:
http://java.sun.com/developer/technicalArticles/Ecommerce/jms/

tag : JMS

2009-02-25 23:22 : __j2ee__jms : コメント : 0 : トラックバック : 0 :
コメントの投稿
非公開コメント

« next  ホーム  prev »

search

ad



counter


tag cloud

category cloud