我编写了一个生产者应用程序,它通过在activeMQ中使用Executer Service来排队JMS消息,并且它运行良好,但问题是需要很长时间才能将消息排入队列。
有三个文件: 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);
}
}
请帮助我!!
答案 0 :(得分:0)
我要看的第一件事就是你的线程用法;你正在为每条消息创建一个新线程,这绝对是你的性能不快的原因之一。你为什么不能让你的线程运行一个发送消息的循环,直到它们用完要发送的消息为止,然后有N个线程分开工作?
您也可能希望在一个单独的线程中运行您的读取器逻辑,它会尽可能快地读取文件并将其读取的内容移交给线程,因此您不必等待文件被读取甚至开始。确保您创建用于在读取器线程之间传递数据的数据结构,并且消息线程是线程安全的!
一旦这样做,如果速度不是您想要的速度,请查看代理的配置。 (并在此处发布,如果您希望有人查看它。)特别是,如果您的消息是持久性的,那么请查看它们被持久化的位置,并查看是否还有其他更快的选项。 (JDBC存储通常是最慢的持久性选项,因此请考虑其他选项。)或者您甚至可以使您的消息非持久化以使其更快;你必须决定你是否可以接受这种权衡。弄清楚您的消息是异步传递还是同步传递;如果同步,则可能需要启用异步。并确保生产者流量控制没有进入(检查代理日志);如果是的话,那么你的消费者可能太慢了,并且正在减慢你的生产者。