当我通过Servlet从JMS队列接收/使用消息时,我遇到了性能问题 对Servlet的简单请求需要10秒钟来执行QueueSession对象的close方法(关闭JMS资源)。 如果我连续多次使用Servlet,则close方法需要20-30秒。 queueConnection.close()的并行执行(一次10个请求)需要6-7分钟。 在同步块中,我将返回值20-30秒来执行queueConnection.close()。
我觉得Servlet线程从池中获取相同的QueueConnection。
不应该让Servlet从池中获取免费连接资源吗?
可以进行以下JMS连接工厂的池设置: 初始和最小池大小,最大池大小,池大小调整数量,空闲超时,最长等待时间。 我已尝试使用Pooling的几个设置,但我没有得到更好的结果。
我想我还必须自己实现池化以汇集我从OpenMQ连接池获得的连接,是吗?
我在队列中有超过40,000条消息,并且消息被参数化(使用消息选择器),这是close-Method延迟的原因(释放JMS Ressources)? 如果我从基于文件的持久性切换到基于jdbc的持久性以获得更好的性能,这是否重要?
在下面的答案中建议使用OpenMQ的UMS组件。 UMS很有用,但我需要使用消息选择器,我认为UMS不支持这一点。
谢谢!
编码:
public class MessageReceiver {
...
public MessageReceiver(){
queueName = "myQueuedestination";
jndiContext = new InitialContext();
queue = (Queue) jndiContext.lookup(queueName);
queueConnectionFactory = (ConnectionFactory) jndiContext
.lookup("myQueueconnectionfactory");
queueConnection = queueConnectionFactory.createConnection();
queueConnection.start();
}
...
public String receive(String KEY, String keyValue) throws Exception {
String returnMessage = null;
String messageSelector = getMessageSelector(KEY, keyValue);
Message m = null;
QueueSession queueSession = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
QueueReceiver queueReceiver = queueSession.createReceiver(queue, messageSelector);
m = queueReceiver.receiveNoWait();
if (queueSession != null) {
try {
queueSession.close();
} catch (JMSException e) {
logger.info("There was an error closing the queueSession");
e.printStackTrace();
}
}
queueSession = null;
if (m != null && m instanceof TextMessage) {
returnMessage = ((TextMessage) m).getText();
}
return returnMessage;
}
...
...
}
的Servlet
...
public void init(ServletConfig config) throws ServletException {
...
messageReceiver = new MessageReceiver();
...
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException
{
...
...
synchronized (this)
{
message = messageReceiver.receive(KEY, keyValue);
}
...
...
}
答案 0 :(得分:1)
IMO如果您觉得必须在servlet中使用消息,那么您的设计可能有问题......我强烈建议您在MDB,Message Driven Bean中接收消息。这是Java Enterprise中用于使用消息的构造。