【问题标题】:How to receive message from wildfly jms queue using consumer如何使用消费者从wildfly jms队列接收消息
【发布时间】:2018-01-28 11:56:22
【问题描述】:

我在从 WildFly JMS 队列接收消息时遇到了一个棘手的问题。我的代码如下:

Session produceSession = connectionFactory.createConnection().createSession(false, Session
                    .CLIENT_ACKNOWLEDGE);
            Session consumerSession = connectionFactory.createConnection().createSession(false, Session
                    .CLIENT_ACKNOWLEDGE);
            ApsSchedule apsSchedule = new ApsSchedule();

            boolean success;
            MessageProducer messageProducer = produceSession.createProducer(outQueueMaxusOrder);
            success = apsSchedule.sendD90Order(produceSession,messageProducer, d90OrderAps);
            if (!success) {
                logger.error("Can't send APS schedule msg ");
            } else {
                MessageConsumer consumer = consumerSession.createConsumer(inQueueDeliveryDate);
                data = apsSchedule.receiveD90Result(consumerSession,consumer);
            }

然后进入receiveD90Result():

public DeliveryData receiveD90Result(Session session, MessageConsumer consumer) {
    DeliveryData data = null;
    try {
         Message message = consumer.receive(10000);

        if (message == null) {
            return null;
        }
        TextMessage msg = (TextMessage) message;
        String text = msg.getText();
        logger.debug("Receive APS d90 result: {}", text);

        ObjectMapper mapper = new ObjectMapper();
        data = mapper.readValue(text, DeliveryData.class);
    } catch (JMSException je) {
        logger.error("Can't receive APS d90 order result: {}", je.getMessage());
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            consumer.close();
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
    return data;
}

但在实现consumer.receive(10000) 时,项目无法从队列中获取消息。如果我使用 MDB 的异步方式来监听队列,我可以从队列中获取消息。如何解决?

【问题讨论】:

    标签: java jms message-queue wildfly-10 activemq-artemis


    【解决方案1】:

    我看不到您在哪里调用 javax.jms.Connection.start()。事实上,看起来您甚至没有对用于您的 javax.jms.MessageConsumer 的 javax.jms.Connection 实例的引用。如果你没有对 javax.jms.Connection 的引用,那么你就不能调用 start() 并且你不能在完成后调用 close() ,所以你会泄漏连接。

    此外,连接是“重”对象,旨在重复使用。您应该为生产者和消费者创建一个连接。此外,如果您的应用程序不打算从多个线程中使用 javax.jms.Session,那么您也不需要多个会话。

    【讨论】:

      【解决方案2】:

      您可以选择多种模式从队列中获取消息。默认情况下,消息队列在使用中是异步的。然而,在某些情况下,您希望同步读取它,例如发送带有帐号的消息并使用另一个队列读取响应并将其与消息 ID 或消息相关 ID 匹配。当您执行接收时,程序正在等待消息在接收中指定的轮询间隔内到达。

      您拥有的代码 sn-p,正如我所见,它使用伪同步方法。如果必须将其用作 MDB,则必须实现消息驱动 bean(EJB 资源)或消息侦听器。

      MDB/Message Listener 的工作方式更加基于事件,而不是超时轮询(如接收),您实现了一个名为 onMessage() 的回调,每次有消息时都会调用该回调。这不是同步调用,而是异步的。您的应用程序可能需要在设计方面进行一些更改。

      【讨论】:

      • 使用异步方式获取消息是真的吗?但是我只是想在wildfly中使用同步方式从jms队列接收消息,代码不会抛出任何异常。
      • 您可以使用同步方式获取消息,您应该 a) 将请求与响应匹配,因为无法保证订单或处理 - 一个应用程序可能响应发布消息可能比另一个更快 b)在确认消息为“丢失”之前,您将轮询多长时间。如果您正在获取特定的堆栈跟踪,请发布您的问题
      猜你喜欢
      • 2012-01-19
      • 2013-08-08
      • 2012-07-14
      • 1970-01-01
      • 2012-05-06
      • 2019-01-02
      • 1970-01-01
      • 1970-01-01
      • 2020-04-05
      相关资源
      最近更新 更多