Glassfish以延迟关闭JMS队列连接/会话资源。 JMS连接池如何工作?

时间:2011-06-27 14:33:33

标签: performance glassfish jms message-queue

当我通过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);
                }

...
...

}

1 个答案:

答案 0 :(得分:1)

IMO如果您觉得必须在servlet中使用消息,那么您的设计可能有问题......我强烈建议您在MDB,Message Driven Bean中接收消息。这是Java Enterprise中用于使用消息的构造。