【问题标题】:Glassfish close JMS queue connection/session resources with delay. How JMS connection pooling works?Glassfish 延迟关闭 JMS 队列连接/会话资源。 JMS 连接池如何工作?
【发布时间】:2011-09-23 14:00:39
【问题描述】:

当我通过 Servlet 从 JMS 队列接收/使用消息时遇到性能问题。
对 Servlet 的简单请求需要 10 秒来执行 QueueSession 对象的 close 方法(关闭 JMS 资源)。 如果我连续多次使用 Servlet,close 方法需要 20-30 秒。 queueConnection.close() 的并行执行(一次 10 个请求)需要 6-7 分钟。 在同步块中,我将返回 20-30 秒的值来执行 queueConnection.close()。

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

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

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

我想我也必须自己实现池化,以池化我从 OpenMQ 连接池获得的连接,对吗?

我在队列中有超过 40,000 条消息并且消息被参数化(使用消息选择器),这是关闭方法延迟(释放 JMS 资源)的原因吗? 如果我从基于文件的持久性切换到基于 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;   
}
...
...
}

小服务程序

...
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);
                }

...
...

}

【问题讨论】:

    标签: performance glassfish jms message-queue


    【解决方案1】:

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

    【讨论】:

    • 我想避免使用 MessageListener(消息驱动 Bean),因为我需要一个简单的应用程序。我想通过诸如localhost:port/myServlet?mykey=abcdef 之类的 URL 通过键(JMS 属性/消息选择器)检索消息
    • 在这种情况下,您可能只需要 OpenMQ 的 UMS 组件(Glassfish 的 JMS 实现) - 看看mq.java.net/4.3-content/ums/umsMain.html
    • 我需要使用消息选择器,但 UMS 不支持。
    猜你喜欢
    • 2012-07-03
    • 2017-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-04
    相关资源
    最近更新 更多