Question

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 performance?

/**
 * 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);
        }
    }
}
Was it helpful?

Solution

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 ActiveMQ OutOfMemory Can't create more threads

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top