The Java EE 7 Tutorial

Previous
Next

46.4 Writing High Performance and Scalable JMS Applications

This section describes how to use the JMS API to write applications that can handle high volumes of messages robustly. These examples use both nondurable and durable shared consumers.

46.4.1 Using Shared Nondurable Subscriptions

This section describes the receiving clients in an example that shows how to use a shared consumer to distribute messages sent to a topic among different consumers. This section then explains how to compile and run the clients using GlassFish Server.

You may wish to compare this example to the results of Running Multiple Consumers on the Same Destination using an unshared consumer. In that example, messages are distributed among the consumers on a queue, but each consumer on the topic receives all the messages because each consumer on the topic is using a separate topic subscription.

In this example, however, messages are distributed among multiple consumers on a topic, because all the consumers are sharing the same subscription. Each message added to the topic subscription is received by only one consumer, similarly to the way in which each message added to a queue is received by only one consumer.

A topic may have multiple subscriptions. Each message sent to the topic will be added to each topic subscription. However, if there are multiple consumers on a particular subscription, each message added to that subscription will be delivered to only one of those consumers.

46.4.1.1 Writing the Clients for the Shared Consumer Example

The sending client is Producer.java, the same client used in previous examples.

The receiving client is SharedConsumer.java. It is very similar to AsynchConsumer.java, except that it always uses a topic. It performs the following steps.

  1. Injects resources for a connection factory and topic.

  2. In a try-with-resources block, creates a JMSContext.

  3. Creates a consumer on a shared nondurable subscription, specifying a subscription name:

    consumer = context.createSharedConsumer(topic, "SubName");
    
  4. Creates an instance of the TextListener class and registers it as the message listener for the shared consumer.

  5. Listens for the messages published to the destination, stopping when the user types the character q or Q.

  6. Catches and handles any exceptions. The end of the try-with-resources block automatically causes the JMSContext to be closed.

The TextListener.java class is identical to the one for the asynchconsumer example.

For this example, you will use the default connection factory and the topic you created in To Create Resources for the Simple Examples.

46.4.1.2 To Run the SharedConsumer and Producer Clients

  1. Make sure that GlassFish Server has been started (see Starting and Stopping GlassFish Server).

  2. Open three command windows. In the first, go to the simple/producer/ directory:

    cd tut-install/examples/jms/simple/producer/
    
  3. In the second and third command windows, go to the shared/sharedconsumer/ directory:

    cd tut-install/examples/jms/shared/sharedconsumer/
    
  4. In one of the sharedconsumer windows, build the example:

    mvn install
    
  5. In each of the two sharedconsumer windows, start running the client. You do not need to specify a topic argument:

    appclient -client target/sharedconsumer.jar
    

    Wait until you see the following output in both windows:

    Waiting for messages on topic
    To end program, enter Q or q, then <return>
    
  6. In the producer window, run the client, specifying the topic and a number of messages:

    appclient -client target/producer.jar topic 20
    

    Each consumer client receives some of the messages. Only one of the clients receives the non-text message that signals the end of the message stream.

  7. Enter Q or q and press Return to stop each client and see a report of the number of text messages received.

46.4.2 Using Shared Durable Subscriptions

The shareddurableconsumer client shows how to use shared durable subscriptions. It shows how shared durable subscriptions combine the advantages of durable subscriptions (the subscription remains active when the client is not) with those of shared consumers (the message load can be divided among multiple clients).

The example is much more similar to the sharedconsumer example than to the DurableConsumer.java client. It uses two classes, SharedDurableConsumer.java and TextListener.java, which can be found under the tut-install/examples/jms/shared/shareddurableconsumer/ directory.

The client uses java:comp/DefaultJMSConnectionFactory, the connection factory that does not have a client identifier, as is recommended for shared durable subscriptions. It uses the createSharedDurableConsumer method with a subscription name to establish the subscription:

consumer = context.createSharedDurableConsumer(topic, "MakeItLast");

You run the example in combination with the Producer.java client.

46.4.2.1 To Run the SharedDurableConsumer and Producer Clients

  1. In a terminal window, go to the following directory:

    tut-install/examples/jms/shared/shareddurableconsumer
    
  2. To compile and package the client, enter the following command:

    mvn install
    
  3. Run the client first to establish the durable subscription:

    appclient -client target/shareddurableconsumer.jar
    
  4. The client displays the following and pauses:

    Waiting for messages on topic
    To end program, enter Q or q, then <return>
    
  5. In the shareddurableconsumer window, enter q or Q to exit the program. The subscription remains active, although the client is not running.

  6. Open another terminal window and go to the producer example directory:

    cd tut-install/examples/jms/simple/producer
    
  7. Run the producer example, sending a number of messages to the topic:

    appclient -client target/producer.jar topic 6
    
  8. After the producer has sent the messages, open a third terminal window and go to the shareddurableconsumer directory.

  9. Run the client in both the first and third terminal windows. Whichever client starts first will receive all the messages that were sent when there was no active subscriber:

    appclient -client target/shareddurableconsumer.jar
    
  10. With both shareddurableconsumer clients still running, go to the producer window and send a larger number of messages to the topic:

    appclient -client target/producer.jar topic 25
    

    Now the messages will be shared by the two consumer clients. If you continue sending groups of messages to the topic, each client receives some of the messages. If you exit one of the clients and send more messages, the other client will receive all the messages.

Previous
Next