views:

341

answers:

2

I'm using ActiveMQ on a simulation of overloading servers in Java. And mainly it goes ok, but when I get over 600 requests the thing just go WTF!

I think the bottleneck is my Master Server which is this guy below. I'm already reusing the connection and creating various sessions to consume messages from clients. Like I said, I'm using about 50-70 sessions per connection, reutilizing the connection and queue. Any idea of what I can reuse/optimize of my components/listener below?

The architecture is the follow:

* = various

Client ---> JMS MasterQueue ---> * Master ---> JMS SlavaQueue ---> * SlaveQueue

Mainly I'm creating a Temp Queue for each session of Master --> Slave communication, is that a big problem on perfomance?

    /**
     * This subclass implements the processing log of the Master JMS Server to
     * propagate the message to the Server (Slave) JMS queue.
     * 
     * @author Marcos Paulino Roriz Junior
     * 
     */
    public class ReceiveRequests implements MessageListener {
     public void onMessage(Message msg) {
      try {
       ObjectMessage objMsg = (ObjectMessage) msg;

       // Saves the destination where the master should answer
       Destination originReplyDestination = objMsg.getJMSReplyTo();

       // Creates session and a sender to the slaves
       BankQueue slaveQueue = getSlaveQueue();
       QueueSession session = slaveQueue.getQueueConnection()
         .createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
       QueueSender sender = session
         .createSender(slaveQueue.getQueue());

       // Creates a tempQueue for the slave tunnel the message to this
       // master and also create a masterConsumer for this tempQueue.
       TemporaryQueue tempDest = session.createTemporaryQueue();
       MessageConsumer masterConsumer = session
         .createConsumer(tempDest);

       // Setting JMS Reply Destination to our tempQueue
       msg.setJMSReplyTo(tempDest);

       // Sending and waiting for answer
       sender.send(msg);
       Message msgReturned = masterConsumer.receive(getTimeout());

       // Let's check if the timeout expired
       while (msgReturned == null) {
        sender.send(msg);
        msgReturned = masterConsumer.receive(getTimeout());
       }

       // Sends answer to the client
       MessageProducer producerToClient = session
         .createProducer(originReplyDestination);
       producerToClient.send(originReplyDestination, msgReturned);
      } catch (JMSException e) {
       logger.error("NO REPLY DESTINATION PROVIDED", e);
      }
     }
    }
A: 

It could have to do with the configuration of the listener thread pool. It could be that up to a certain threshold number of requests per second the listener is able to keep up and process the incoming requests in a timely way, but above that rate it starts to fall behind. it depends on the work done for each incoming request, the incoming request rate, the memory and CPU available to each listener, and the number of listeners allocated.

If this is true, you should be able to watch the queue and see when the number of incoming messages start to back up. That's the point at which you need to increase the resources and number of listeners to process efficiently.

duffymo
So my best approach is put more listeners there on the master?
Marcos Roriz
If that's what your data is telling you, then yes. The only way to tell what's happening is to observe the queues and measure the listeners.
duffymo
+1  A: 

Well, After some reading I found out how to optimize.

We should reuse some session variables, such as the sender and tempqueue. Instead of creating new ones.

Another approach is put the stack size for thread in Java lower, following this link http://stackoverflow.com/questions/1808782/activemq-outofmemory-cant-create-more-threads

Marcos Roriz