Table of Contents
This chapter describes the special functions of JEUS MQ, including message bridges, message sort, Global Order, message groups, and message management.
Message bridge is a function that connects two different MQs. The two different MQs can be classified into the following cases.
Different versions of the same MQ service (two different versions of JEUS MQs that are not compatible with each other)
Different MQ services (JEUS MQ and another vendor's MQ such as WebLogic)
[Note]
It is not recommended to configure a message bridge between the same versions of JEUS MQ services.
If you are using the same versions, it is safer and more efficient to connect a client to a remote destination. If a bridge between the same JEUS MQ service versions must be configured, to distinguish the bridge from general message services between the MQs, add the following option to the server's execution script:
-Djeus.jms.client.use-single-server-entry=false
The following two configurations are required to use a message bridge.
Configure two bridge connections for each end of a message bridge.
Configure the actual bridge entry that connects the two bridge connections.
The following example shows how to configure a message bridge between WebAdmin MQ and WebLogic 10.3 MQ.
Message bridges run independently from JEUS MQ. To set up a message bridge, go to [Resources] > [Message Bridge] from the left pane of the screen.
Configure JEUS MQ and WebLogic 10.3 MQ in the Message Connections section of the Message Bridge page, and then configure the connection between two MQs in the Message Entries area. Click on the name of the Message Connection or Message Entry to configure its properties. When the Connection page or Bridge page appears, configure the required items and click [OK] to save the configuration. To change the settings, click [Reset].
The following are the Connection and Bridge setting pages.
If there is a message producer but no consumer in a queue, or if there is a message consumer but the message reception is relatively slow, messages accumulate in the queue. When this happens, you can use a message sort function sort the queued messages according to key values that you define.
Messages can also be accumulated in a durable subscriber that is similar to a queue, and when this happens, you can use the message sort function. The key values include the basic JMS property values or property values that you define (User Property).
Message sorting is configured differently for servers and clients. To enable message sorting, servers are configured using WebAdmin and clients are configured in the message properties.
To configure a server for message sorting, go to [Servers] > [Select a Server] > [Engine] > [JMS Engine] > [Message Sort]. To enable message sorting, a server has to be configured as in the following.
The previous message sorting configuration can be applied for a destination or durable subscriber. For more information, refer to "3.2.1. Configuring Destinations" and "3.2.2. Configuring Durable Subscribers".
The messages that do not correspond to the configured key value are not sorted, and the original order is maintained. This means that if there is a mixture of messages that correspond to and do not correspond to a key value in the queue, the former will be sorted in the configured order, and the latter will be kept in their original order.
Global Order ensures that the messages queued at the destination are delivered to a client exactly one at a time. In general, messages are processed simultaneously by multiple clients and there is no way to control the processing order of the messages. If multiple messages are sent in parallel, they are processed regardless of the order in which they are sent. Although this does not impact system performance, the global order function can be used to ensure the message processing order.
The client can use the Global Order API without additional configurations.
For a single message consumer, Global Order does not change the existing order. Hence, to use Global Order, multiple message consumers have to be configured for the destination.
In the following example, a message sender creates a Producer and casts the message to JeusMessageProducer, and then calls the Global Order API.
JeusMessageProducer producer = (JeusMessageProducer) session.createProducer(queue); // Set Global Order and assign a name. producer.startGlobalOrder("GLOBAL-ORDER-NAME"); // If a name is not specified. //producer.startGlobalOrder();
The GLOBAL-ORDER-NAME
identifies the
Global Order. If it is not configured, a random name is assigned.
The Global Order name can be shared by multiple clients. If this function is used with clustering, the processing order is applied to the entire cluster.
Message group is a function that sends a group of messages that have the same purpose and are all queued at a destination to a single message consumer. For example, if 10 messages are set in a group, the messages are not delivered to the consumer until all 10 messages are in the queue. This is similar to the transaction mechanism and can be used for similar purposes, and it can also be used with clustering.
The server configurations are required in the Destination page to enable message group. For more information about the page, refer to "3.2.1. Configuring Destinations".
Make sure that you specify a value for 'Expiration Time'. Otherwise, an incomplete message group is created that is kept permanently in the server. This can cause unnecessary memory usage.
In the client configuration, you must configure the message producer and message consumer settings.
Configuring the Message Producer
To configure the message producer, use the message's User Property.
Message msg = session.createMessage(); // Set the Message Group name. The name identifies the Group. msg.setStringProperty("JMS_JEUS_MSG_GROUP_NAME", "MESSAGE-GROUP-NAME
"); // Set the order of the messages in the Group. The messages are delivered to the destination in this order. msg.setIntProperty("JMS_JEUS_MSG_GROUP_NUMBERING", 1); producer.send(msg); msg = session.createMessage(); msg.setStringProperty("JMS_JEUS_MSG_GROUP_NAME", "MESSAGE-GROUP-NAME
"); msg.setIntProperty("JMS_JEUS_MSG_GROUP_NUMBERING", 2); producer.send(msg); . . . msg = session.createMessage(); msg.setStringProperty("JMS_JEUS_MSG_GROUP_NAME", "MESSAGE-GROUP-NAME
"); msg.setIntProperty("JMS_JEUS_MSG_GROUP_NUMBERING", 10); // Set the last message of the Group. msg.setBooleanProperty("JMS_JEUS_MSG_GROUP_END", true); producer.send(msg);
Configuring the Message Consumer
The message consumer receives the message group as an ObjectMessage that contains the messages.
// The message group is a ObjectMessage that is a list of the messages. ObjectMessage result = (ObjectMessage) receiver.receive(TIME_OUT); List list = (List) result.getObject(); int cnt = 1; // Each message can be retrieved from the list one at a time. for(Object obj : list) { // Messages are processed in the order specified by the message producer. TextMessage msg = (TextMessage) obj; . . . }
Message management functions are used to check, move, and delete messages that arrive at a destination while JEUS MQ messaging services are enabled. The message management functions can be grouped into the following three categories.
Message Monitoring Functions
They monitor messages in a destination.
Message Control Functions
They control messages by moving, deleting, exporting, and importing them.
Destination Control Functions
They control destinations for flexible message monitoring and control.
Message monitoring and control are supported for the messages in a queue or durable subscriber. Destination control is provided for the messages in the queues and topics.
With message monitoring functions, you can monitor messages in a queue or durable subscriber and retrieve detailed message information.
You can monitor messages in a queue or durable subscriber by selecting the ID, type, creation time, and other information. To search, delete, move, export, and perform other tasks, select a message from the list.
JMS messages are created and consumed quickly. If a message is searched for without enabling the Consumption Suspended setting in the Destination page, the search result may contain a message that has already been consumed. It is recommended to enable the Consumption Suspended setting before searching for the message.
Following are the steps for searching the message list.
Different menus are used depending on where the message is.
Messages in a Queue
Go to [Monitoring] > [JMS] > [Destinations] > [Server], and select a server from the drop-down list. The list of destinations in the server appears.
Messages in a Durable Subscriber
Go to [Monitoring] > [JMS] > [Durable Subscriptions] > [Server], and select a server from the drop-down list. The list of Durable Subscriptions of the server appears.
If you click [Browse] on the Queue or Durable Subscription pages, the Message List window appears where you can retrieve a list of messages.
You can look for a specific message in the message list by specifying the message ID, type, or creation type, or by using the message selector. To retrieve all messages in the Queue or Durable Subscription, click [OK] without selecting any items in the Message List window.
The following shows the list of messages at the destination. You can delete, move, or export a message. If you click on the message ID in the Message ID column, you can see detailed information about each message.
The detailed information about messages in the Queues or Durable Subscribers can be retrieved. It is possible to check the header information defined in JMS specification, message information, and configured properties.
JMS messages are created and consumed quickly. If information about a message is retrieved without enabling the Consumption Suspended setting in the Destination page, the message may have already been consumed and no longer exists. It is recommended to enable the Consumption Suspended setting before searching for the message. In particular, if you are modifying the information about of a message without enabling the Consumption Suspended setting, the modifications may not be saved.
The following are the steps for retrieving detailed information about messages.
On the message list page, mark the Message ID of a specific message.
The following screen shows the retrieved message information.
You can change the content and properties of a message if the message type is 'Text'. To save changes, click [OK]. To undo changes, click [Reset].
The following message control functions are provided in WebAdmin.
Moving Messages
Moves messages to another destination on a server or cluster.
Deleting Messages
Deletes messages from the Queue or Durable Subscriber.
Exporting Messages
Exports certain messages on a server or cluster to another server or cluster.
Importing Messages
Imports the exported messages to a specific destination on a server or cluster.
You can move messages to another destination on a server or cluster. This function is useful for handling errors such as sending messages to a wrong destination.
JMS messages are created and consumed quickly. If the messages are moved without enabling the Consumption Suspended setting in the Destination page, the search result may contain a message that has already been consumed. It is recommended to enable the Consumption Suspended setting before moving a message.
2. You can move messages to another destination. If a message at the target destination has the same ID as the one you moved, the new message overwrites the existing one. But if the existing message is already sent to a client while being overwritten, the message may not be synchronized between the client and the server. To avoid this problem, enable the Consumption Suspended setting before moving a message.
The following example shows how to move a message.
Select the message to move from the list of messages, and then click [move].
In the Move Message page, from the Target drop-down list, select a destination. If you want to move all the messages in the queue or durable subscriber, mark All. When you are done, click [OK]. The selected messages will be moved to the destination.
You can delete messages that are no longer needed.
JMS messages are created and consumed quickly. If the messages are deleted without enabling the Consumption Suspended setting in the Destination page, the search result may contain a message that has already been consumed. It is recommended to enable the Consumption Suspended setting before deleting a message.
The following example shows how to delete a message.
Select the message to delete from the list of messages, and then click [remove].
To delete a message from the server, in the Remove Message window, click [OK]. To move all messages at a destination, mark All.
The messages in a Queue or Durable Subscriber can be exported to another server or cluster.
JMS messages are created and consumed quickly. If the messages are exported without enabling the Consumption Suspended setting in the Destination page, the search result may contain a message that has already been consumed. It is recommended to enable the Consumption Suspended setting before exporting a message.
The following example shows how to export a message.
From the list of messages, select the message to export, and then click [export].
To export all messages at a destination or a durable subscriber, mark All in the Message Export window. Click [OK] to export the message(s) and then download the "message.xml" file through the browser.
Messages can be imported to a destination as XML formatted data. An imported message is treated as a new message. Therefore, a new message ID is assigned to the message when it is imported to a destination.
If the 'Overwrite' checkbox is checked when importing messages, some messages that are overwritten may already have been delivered to the clients. In this case, messages are imported successfully but incorrectly overwritten. Hence, it is recommended to enable the Consumption Suspended setting before importing a message.
The following example shows how to import a message.
Go to [Monitoring] > [JMS] > [Destinations] > [Server] in WebAdmin. Click [import] of the destination to import messages to.
Enter the required properties in the Message Import page, and then click [OK]. To overwrite an existing message at the destination that has the same message ID as the imported one, check Overwrite. The message with the same message ID as the imported message will be overwritten.
You can suspend or resume message production and consumption at a destination.
You can suspend or resume message production and consumption at a destination. When message production is suspended at a destination, you cannot create a message.
In WebAdmin, go to [Monitoring] > [JMS] > [Destinations] > [Server]. A list of destinations on a server appears.
With the Production Suspended setting, you can suspend or resume message production at a destination. The message production state of the destination can be changed by using the true or false button.
Configuration Value | Description |
---|---|
true | Message production at the destination is currently suspended. |
false | Messages are being normally produced at the destination. |
When a message is sent to a destination where message production has been suspended ("Production Suspended" is set to true), the server waits for a given time and throw a jeus.jms.common.destination.InvalidDestinationStateException through the ExceptionListener.
You can suspend or resume message consumption at a destination. If you suspend message consumption is suspended at a destination, messages cannot be consumed at the destination.
In WebAdmin, go to [Monitoring] > [JMS] > [Destinations] > [Server]. A list of destinations on the server appears.
With the Consumption Suspended setting, you can control message consumption at the destination. Message consumption at a destination state can be changed by using the true or false button.
Configuration Value | Description |
---|---|
true | Message consumption from the destination is currently suspended. |
false | Messages are being normally consumed from the Destination. |
When a message at a destination whose message consumption has been suspended ("Consumption Suspended" is set to true) is being consumed, the server operates as if there were no messages at the destination.
In JEUS MQ, reliable message transmission is ensured by using a persistent store even in the case of a failure. A persistent store guarantees reliable message delivery between a JEUS MQ server and the message recipient. But it does not guarantee reliable message delivery when a message is sent to the server and when the server or the client fails.
To compensate for this limit, JEUS MQ provides a function to increase the reliability between the sender and the JEUS MQ server using a local persistent queue (hereafter LPQ) that is similar to the persistence store. LPQ saves data in the local storage and ensures that the stored data is processed normally. JEUS MQ saves messages using LPQ before they are sent and makes continuous attempts to send them until they are successfully sent to the server. Thus, LPQ increases reliability of the message transmission between the sender and the server.
Reliable message transmission using LPQ has the following characteristics.
Retransmitting messages until it succeeds regardless of the server status
Recovery of messages that failed to be sent due to abnormal client status
Asynchronous messaging
When the JMS client is sending a message, if the client is a Java EE application that is deployed on the JMS server, which is the message recipient, the message is not sent over the network to improve performance. In this case, the LPQ configuration is ignored.
To use reliable messaging through LPQ, you must activate LPQ first. You need to create a storage to store messages, a queue for processing, and an object for managing the messages.
To execute a standalone client that uses LPQ, LPQ and storage libraries are additionally needed. The libraries are jeus-lpq-spi.jar, jeus-lpq.jar, jms-extentsion.jar, and jeus-store.jar, which are in the JEUS_HOME/lib/system directory.
To activate LPQ, choose one of the following ways:
Using the JVM option
When a JEUS MQ client is executed, the JVM option is applied to activate LPQ as in the following. This option activates LPQ when JMS creates a connection in the client.
-Djeus.jms.client.send-by-lpq-only=true
Using the LPQ configuration file
When a JEUS MQ client is executed, LPQ is activated as it is configured by reading the file if the LPQ configuration file can be found in the designated path. For detailed information about the LPQ configuration file path and how to configure it, refer to "6.6.4. LPQ Configuration".
Using the API for JEUS
LPQ can be activated in the client source code by using the following API of JeusSession, a JEUS session object.
public void startLPQ();
1. The LPQ operation can be configured through the configuration file or system property when the JVM option or JEUS API is used. The default value is applied for unconfigured items. For detailed information about LPQ configuration, refer to "6.6.4. LPQ Configuration".
2. If JEUS API is not used, when LPQ will be activated is not specified. In this case, LPQ is activated when the JVM creates the first connection. LPQ terminates when the last connection is closed. However, if LPQ still has messages, it does not terminate until they have been processed.
Once LPQ is activated, a message can be sent more reliably by using LPQ. There are three configuration units for sending messages through LPQ.
JVM Unit Configuration
Used when LPQ is activated by using the JVM option. All messages from the JVM are sent through LPQ.
ConnectionFactory Unit Configuration
When the Connection Factory names to use LPQ are added to the JVM option, all the messages that are sent from the connections created by the Connection Factory are sent through LPQ. Connection factory names are separately by a commas (,).
jeus.jms.client.connection-factory-for-lpq=<ConnectionFactoryName1,ConnectionFactoryName2,..>
JMS specifications do not have naming limits for connection factories. However, if a commas is used, the above option cannot be normally applied and the LPQ function cannot be used.
Session Unit Configuration
Used to specify whether to send messages to each session by using LPQ. The following API of the JEUS message sender object can be used to send all messages that will be sent to the session by using LPQ.
public void setLPQOnly(boolean lpqOnly);
Message Unit Configuration
Used to specify whether to send each message through LPQ. Either use the following APIs of the JEUS message sender object, or configure the User Property of the message.
// JEUS APIs
public void sendWithLPQ(Message message);
public void sendWithLPQ(Message message, int deliveryMode, int priority, timeToLive);
public void sendWithLPQ(Destination destination, Message message);
public void sendWithLPQ(Destination destination, Message message, int deliveryMode, int priority, timeToLive);
// User Property of JMS message
Message msg = session.createMessage();
msg.setBooleanProperty("JMS_JEUS_USE_LPQ", true
);
LPQ activation by using JEUS API only enables LPQ to be used in the corresponding session. LPQ configuration for messages that are sent using other sessions is ignored.
When LPQ is used to send messages, the messages are processed asynchronously. Therefore, the client does not know whether a message has been sent or not. LPQ provides a listener to be able to get the message transmission time and result.
The following jeus.jms.LPQMessageListener interface is provided to get the message transmission result through the listener.
package jeus.jms; public interface LPQForwardListener { /** * Event that is triggered when message transmission is complete * @param message = A transmitted message */ public void onComplete(Message message); /** * Event that is triggered when an Exception occurs while a message is being transmitted * @param message = A message to transmit * @param e = An exception that occurred */ public void onException(Message message, Exception e); /** * Event that is triggered when the message transmission fails * * @param message = A message that failed to be transmitted * @param cause = A cause for the failed transmission */ public void onFailure(Message message, Throwable cause); }
You can retrieve the message transmission result by setting the implemented LPQMessageListener to the JeusSession object by using the following API.
public void setLPQMessageListener(jeus.jms.LPQMessageListener lpqMessageListener);
When using a JEUS object to activate LPQ, you can use the following API to both activate LPQ and set the listener.
public void startLPQ(jeus.jms.LPQMessageListener lpqMessageListener);
LPQ Configurations include items for processing failed transmissions, operation during disconnection, and the storage size or location.
The following describes LPQ configuration items.
Common Items
Item | Type | Description |
---|---|---|
jeus.lpq.name | String | LPQ name. (Default: JEUS_LPQ) |
jeus.lpq.max-message-count | int | Maximum number of messages that LPQ can process at a time. (Default: 819200) |
jeus.lpq.time-to-live | long | How long a message can remain in LPQ. (Default: 43200000ms (12hours)) |
Transmission-Related Items
Item | Type | Description |
---|---|---|
jeus.lpq.retry-limit | int | Number of attempts to resend a failed message. If set to 0 or less, retries are attempted indefinitely. (Default: -1) |
jeus.lpq.retry-interval | long | Transmission interval for resending a message. (Default: 1000ms) |
jeus.lpq.retry-interval-increment | long | Increment to increase the retry interval every time a message is resent. (Default: 0ms) |
Reconnection-related Items
Item | Type | Description |
---|---|---|
jeus.lpq.reconnect-retry-interval | long | Interval for reconnecting when the connection is lost. (Default: 5000ms) |
Storage-related Items
Item | Type | Description |
---|---|---|
jeus.lpq.store.store-mode | int | Storage type. Set to 1 to use the journal store and 2 to use the memory storage. (Default: 1) |
jeus.lpq.store.journal.store-base- dir | String | Name of the directory to create the Store in. The name must be unique per LPQ configuration and two or more concurrent connections are not allowed. If set to a relative path, it is set to a path under the directory where the configuration file exists or JVM is running. (Default: JEUS_LPQ_STORE) |
jeus.lpq.store.journal.initial-log- file-count | int | Number of log files to create initially when creating the Journal Store. (Default: 2) |
jeus.lpq.store.journal.max-log-file- count | int | Maximum number of log files to create. (Default: 10) |
jeus.lpq.store.journal.log-file-size | String | Log file size. (Default: 64M) Append one of the following text after an integer value or number.
|
The following describes how to configure LPQ. The order of configuration is runtime property configuration, the configuration file, and then the JVM option.
Configuration File
When LPQ configuration file exists in the specified location, the configurations in the file are applied when LPQ is activated. Find the configuration file in order of DEPLOYED_HOME/myApp/WEB-INF/, DEPLOYED_HOME/myApp/META-INF/, and DEPLOYED_HOME/myApp/. The default value of the detailed configuration file path is 'jeus-lpq.properties' and can be changed using the following option.
-Djeus.jms.client.lpq-configuration-path=jeus-lpq.properties
The following is an example of the LPQ configuration file. The name of this example file is 'jeus-lpq.properties', and the file exists in 'JEUS_HOME/templates/lpq/'.
#JEUS Local-Persistent-Queue Configuration #[commons] jeus.lpq.name=JEUS_LPQ jeus.lpq.max-message-count=819200 jeus.lpq.time-to-live=43200000 #[forward] jeus.lpq.retry-limit=-1 jeus.lpq.retry-interval=1000 jeus.lpq.retry-interval-increment=0 #[reconnect] jeus.lpq.reconnect-retry-interval=5000 #[store] jeus.lpq.store.store-mode=1 #[journal-store] jeus.lpq.store.journal.store-base-dir=JEUS_LPQ jeus.lpq.store.journal.max-log-file-count=10 jeus.lpq.store.journal.initial-log-file-count=2 jeus.lpq.store.journal.log-file-size=64M
System Property
The previous configuration items can be set as system properties by using each item name as the key. For instance, if the LPQ name is configured, the JVM option can be configured when a JEUS MQ client is executed as in the following.
-Djeus.lpq.name=<jeus lpq name>
Runtime Configurations can be modified by changing the client source code.
System.setProperty("jeus.lpq.name", <jeus lpq name>);