简体   繁体   中英

activeMQ producer taking long time in sending messages

I have written a producer application that enqueue JMS messages by using Executer Service in activeMQ and it is working finely but the problem is it's taking long time to enqueue messages .

there are three files: 1. ExecutePushServer.java 2. ActiveMQProducer.java 3. SendPush.java

ExecutePushServer.java:

package com.rh.pushserver;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import org.apache.log4j.Logger;

public class ExecutePushServer {

/**
 * @uthor ankit
 */

static int maxThread = 0;
static BufferedReader br = null;
static String fileLocation = null;
static List<String> tokenList = new ArrayList<String>();
private static String txt;
static Properties configFile = new Properties();
private final static Logger logger = Logger
        .getLogger(ExecutePushServer.class.getName());

public static void main(String[] args) {
    // TODO Auto-generated method stub
    try {
        configFile.load(ExecutePushServer.class.getClassLoader()
                .getResourceAsStream("config.properties"));
        maxThread = Integer.valueOf(configFile.getProperty("POOL_SIZE"));

        fileLocation = configFile.getProperty("LOCATION");

        txt = configFile.getProperty("txt");
        logger.info("Message text is : " + txt);

        br = new BufferedReader(new FileReader(fileLocation));

        ActiveMQProducer mqProducer = new ActiveMQProducer();

        tokenList = getList(br);
        logger.info("tokenList created.");


        ExecutorService executor = Executors.newFixedThreadPool(maxThread);
        for (String id : tokenList) {
            Runnable work = new SendPush(mqProducer, id);
            executor.execute(work);
        }

        // This will make the executor accept no new threads
        // and finish all existing threads in the queue
        logger.info("All Ids Entered in Pool.");
        executor.shutdown();

        while (!executor.awaitTermination(10, TimeUnit.MINUTES)) {
            logger.info("Inside awaitTermination");
        }

        mqProducer.closeConnection();

    } catch (IOException e) {
        logger.error("Error in Reading File" + e);

    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        logger.error("Error in termination of executer" + e);
    } finally {
        try {
            if (br != null)
                br.close();

        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

}

private static List<String> getList(BufferedReader br) {
    // TODO Auto-generated method stub
    String currentLine;
    try {
    while ((currentLine = br.readLine()) != null) {
        tokenList.add(currentLine);
    }

    return tokenList;

    } catch (IOException e) {
        logger.error("Error occured in creating tokenList !" + e);
        return null;
    } 
}

}

ActiveMQProducer.java

package com.rh.pushserver;


import java.io.IOException;
import java.util.Properties;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.MessageProducer;
import javax.jms.Session;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.log4j.Logger;

public class ActiveMQProducer {

/**
 * @uthor ankit  
 */


private final String url = ActiveMQConnection.DEFAULT_BROKER_URL;
private final String subject = "PUSH_NOTIFICATION";
private Connection connection;
private Session session;
private String txt=null;
private MessageProducer producer;
private MapMessage mapMessage;
static Properties configFile = new Properties();
private final static Logger logger=Logger.getLogger(ActiveMQProducer.class.getName());

public ActiveMQProducer() {
    try {
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url);
        connection = connectionFactory.createConnection();
        connection.start();

        logger.info("Connection Created.");

        session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        Destination destination = session.createQueue(subject);
        producer = session.createProducer(destination);

        logger.info("Producer generated");

               configFile.load(ActiveMQProducer.class.getClassLoader().getResourceAsStream("config.properties"));

        txt=configFile.getProperty("txt");

        mapMessage = session.createMapMessage();
    } catch (JMSException e) {
        // TODO Auto-generated catch block
        logger.error("Error JMS Exception occured in creating connection"+e);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        logger.error("Exception occured while opening file "+e);
    }
}
public MessageProducer getProducer() {
    return producer;
}

public void enqueueMessage(String id){
    try {   
        mapMessage.setString("ID", id);
        mapMessage.setString("DISPLAY_STRING", txt);
        mapMessage.setInt("BADGE_COUNT", 1);
        mapMessage.setString("DEVICE_TYPE", "ANDROID");

        producer.send(mapMessage);
        logger.info("Sent on : "+id);

    } catch (JMSException e) {
        // TODO Auto-generated catch block
        logger.error("Error while Enqueue"+e);
    }
}

public void closeConnection(){
    try {
        connection.close();
        logger.info("Connection closed");
    } catch (JMSException e) {
        // TODO Auto-generated catch block
        logger.error("Error in connection closer"+e);
    }
}

}

SendPush.java

package com.rh.pushserver;



public class SendPush implements Runnable {
/**
 * @uthor ankit
 */

private String id;
private ActiveMQProducer mqProducer;


public SendPush(ActiveMQProducer mqProducer,String id) {

    this.id=id;
    this.mqProducer=mqProducer;
}

@Override
public void run() {

    mqProducer.enqueueMessage(id);
}

}

please help me !!

The first thing I'd look at is your thread usage; you're creating a new thread for each message, which could definitely be a big part of why your performance isn't faster. Why can't you have your threads run a loop that sends messages till they run out of messages to send, and then have N threads that split the work?

You'll also probably want to run your reader logic in a separate thread, where it reads the file as fast as it can and hands off the things it reads to the threads, so you don't have to wait while the file is read to even get started. Make sure you make the data structures that you use to pass data between the reader threads and the message threads are thread-safe!

Once you do that, if the speed isn't where you want it to be, look at the broker's configuration. (And post it here, if you want someone to look at it.) In particular, if your messages are persistent, then look at where they're being persisted and see if there are other options that would be faster. (JDBC storage is generally the slowest persistence option, so consider other options.) Or you might even be able to make your messages non-persistent to make them faster; you'll have to decide if you can live with that trade-off. Figure out whether your messages are being passed asynchronously or synchronously; if sync, you might want to enable async instead. And make sure that producer flow control isn't kicking in (check the broker logs); if it is, then your consumers are probably too slow and are slowing down your producers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM