【问题标题】:Java JMS ActiveMQ - Close the session used to create a consumer with MessageListenerJava JMS ActiveMQ - 关闭用于使用 MessageListener 创建消费者的会话
【发布时间】:2021-01-19 00:14:39
【问题描述】:

我有一个使用 ActiveMQ 的 JAVA 应用程序。按照为每个消费者使用特定“会话”的建议(以避免来自不同线程的会话并发问题),我在创建每个新消费者之前创建一个新会话。这些消费者使用 MessageListener 以异步方式收集他们的消息。

当消费者关闭时,我还想关闭用于(并显式创建)创建此消费者的会话,但我无权访问用于创建我要关闭的特定消费者的会话(消费者的“MessageConsumer”对象中不存在此方法)。 我不想让所有这些会话保持打开状态,因为消费者正在动态连接和断开连接,并且打开(和未使用的)会话的最终数量会非常高。

有没有办法访问用于创建使用 MessageListener 的特定“消费者”(MessageConsumer 对象)的“会话”?

当使用 MessageListerner 的使用者关闭时,还有其他方法可以关闭会话吗?

是否还有一种可能是自动清除没有任何相关资源(消费者、生产者等)的“会话”?

这是我的代码的 sn-p:

    Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
    MessageConsumer consumer = session.createConsumer(session.createQueue(queueName));
    consumer.setMessageListener(new CustomMessageListener(locWSInstance));

【问题讨论】:

    标签: java jms activemq


    【解决方案1】:

    您可以将会话和使用者传递给您的 CustomerMessageListener,它可以在您的 CustomMessageListener 的关闭生命周期中调用关闭。否则,您需要某种 Manager/Tracker 类来跟上所有对象以防止资源/内存泄漏。这与 JDBC 没有什么不同!有状态通信带来了性能和好处,但您必须跟踪清理工作作为权衡。

    1. 使用 PooledConnectionFactory

    2. 确保对生命周期逻辑进行单元测试。这是等待发生的资源泄漏/内存泄漏。

    3. each 对象周围执行适当的 try { } catch {} finally {} 逻辑,以确保对所有对象调用关闭,并且您不会在 .close() 方法抛出泄漏在调用所有 .close() 之前出现异常并退出代码路径(见下文)

       public void deactivate() {
      
           if(consumer != null) {
              try {
                  consumer.close();
              } catch (JMSException e) {
                  // do some logging
              } finally {
                  consumer = null;
              } 
           }
      
          if(session != null) {
              try {
                  session.close();
              } catch (JMSException e) {
                  // do some logging
              } finally {
                  session = null;
              } 
           }
       }
      

    【讨论】:

    • 非常感谢您的回复。请,您能否指定我如何检测消费者何时在我的 CustomMessageListener 的关闭生命周期内关闭?据我所知,我只能在此侦听器中定义“onmessage()”方法,所以,我怎么知道消费者何时关闭然后关闭会话(使用我也将传递给侦听器的变量作为你正确地建议)?提前致谢。
    • 您使用的是什么 Java 运行时?通常,您会有某种 init()/destroy() 或 activate()/deactivate() 类型约定,其中提供服务和维护某些状态的类具有启动和关闭它们的生命周期。 Spring、OSGi、Web 容器等
    猜你喜欢
    • 2014-10-23
    • 2019-10-27
    • 1970-01-01
    • 2011-06-12
    • 1970-01-01
    • 1970-01-01
    • 2020-12-09
    • 1970-01-01
    • 2015-01-28
    相关资源
    最近更新 更多