首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Glassfish延迟关闭JMS队列连接/会话资源。JMS连接池是如何工作的?

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

Stack Overflow用户
提问于 2011-06-27 22:33:33
回答 1查看 1.3K关注 0票数 0

当我通过Servlet从JMS队列接收/消费消息时,我会遇到性能问题。

Servlet上的一个简单请求需要10秒来执行QueueSession对象的close方法(关闭JMS资源)。如果我连续多次使用Servlet,close方法需要20-30秒。对于queueConnection.close()来说,并行执行(一次10个请求)需要6-7分钟。在synchronized块中,我返回一个20-30秒的值来执行queueConnection.close()。

我有一种感觉,Servlet线程从池中获取相同的QueueConnection。

难道不应该让Servlets从池中获取空闲的连接资源吗?

可以对JMS连接工厂的池进行以下设置:初始池大小和最小池大小、最大池大小、池大小调整数量、空闲超时和最长等待时间。我已经尝试了几种池化设置,但没有得到更好的结果。

我认为我还必须实现池化自己来池化从OpenMQ连接池获得的连接,对吗?

我在队列中有超过40,000条消息,并且消息是参数化的(使用消息选择器),这是close-Method延迟的原因(释放JMS资源)吗?如果我从基于文件的持久化切换到基于jdbc的持久化来获得更好的性能,这有关系吗?

在下面的答案中,建议使用OpenMQ的UMS组件。UMS很有用,但我需要使用消息选择器,我认为UMS不支持这一点。

谢谢!

编码:

代码语言:javascript
复制
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

代码语言:javascript
复制
...
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);
                }

...
...

}
EN

回答 1

Stack Overflow用户

发布于 2011-06-27 22:44:15

如果您觉得必须在servlet中使用消息,那么您的设计可能存在问题……我强烈建议您在MDB中接收消息,即消息驱动Bean。这是Java Enterprise中为使用消息而创建的结构。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6494516

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档