RishiPandey RishiPandey - 19 days ago 5
Java Question

JMS Producer and Consumer taking too much time. Why?

I have used ActiveMQ as broker and JMS to receive async. messages in queue then start consuming these messages as soon as message comes in queue.
For this i have Written producer and consumer code.
Everything is working fine but the entire process is taking too much time around 2-3 minutes for 10000 records.(i have used a loop just for simulation)
Below is the entire code:

This is JMS Producer:

public class JmsMessageProducer
{
public void jmsListener(String obj) throws Exception
{
BrokerService broker = BrokerFactory.createBroker(new URI("broker:(tcp://localhost:61616)"));
broker.start();
Connection connection = null;
Session session = null;
MessageProducer producer = null;
try
{
long millis = System.currentTimeMillis() % 1000;
// Producer
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");
connection = connectionFactory.createConnection();
session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);

Queue queue = session.createQueue("customerQueue3");

MessageConsumer consumer = session.createConsumer(queue);
consumer.setMessageListener(new ConsumerMessageListener("Consumer3"));
connection.start();

producer = session.createProducer(queue);

for(int i=0; i<10000; i++)
{
String payload = "Important Task"+i;
Message msg = session.createTextMessage(payload);



System.out.println("Sending text '" + payload + "'");

producer.send(msg);
}

long millis2 = System.currentTimeMillis() % 1000;
long millis3 = millis2- millis;
System.out.println("time taken: "+ millis3 );

}
finally
{
if(producer != null)
{
producer.close();
}
if (session != null)
{
session.close();
}
if (connection != null)
{
connection.close();
}
broker.stop();
}
}
}


This is listener code:

public class ConsumerMessageListener implements MessageListener
{
private String consumerName;

public ConsumerMessageListener(String consumerName)
{
this.consumerName = consumerName;
}

DummyAdapter adapter = new DummyAdapter();
public void onMessage(Message message)
{
TextMessage textMessage = (TextMessage) message;
try
{
System.out.println(consumerName + " received "+ textMessage.getText());
// adapter.dummy(textMessage.getText());
}
catch (JMSException e)
{
e.printStackTrace();
}
}
}


I am doing this first time.
Can anyone tell me why is this process taking too much time?
What am i doing wrong?

Answer

I am not sure about the SLA that you are expecting, but your message Broker is working at the rate of 80 messages/sec (approx.), which is NOT bad.

And one issue with your code is session.createProducer(queue) is the problem for the time lag as it is a costly operation (takes time) and you can use a single producer object to produce multiple messages.

So create MessageProducer outside the for loop as shown below:

MessageProducer producer = session.createProducer(queue);
for(int i=0; i<10000; i++) {
    String payload = "Important Task"+i;
    Message msg = session.createTextMessage(payload);

   System.out.println("Sending text '" + payload + "'");

   producer.send(msg);
}

You have to close both producer and session objects in the finally block.

P.S.: Also, as a side note, it would be good if you name your producer class name as JmsMessagePrducer instead of JmsMessageListener as in general we use the name as Listener only for JMS consumers.

UPDATE:

I just want to know that is it good to process around 80 messages/sec.? that too without any operation after consuming. What if add more tasks after message consumption from queue, like inserting in db or some business operation.

It is NOT wise to simply tell that 80 messages/sec is better or 50 messages/seconds is better without knowing which Server/OS/etc...(parameters need to be considered). When it comes to performance requirements you need to specify/define the requirements first.

Your current code processes around 80 messages/sec, then that is what your application benchmark is, for the given conditions. So if you feel like it is NOT meeting your performance requirements, then you need to configure multiple JMS listeners to process messages parallelly and change your design.