【问题标题】:MessageConsumer is not consuming messagesMessageConsumer 不消费消息
【发布时间】:2012-07-30 10:51:33
【问题描述】:

我的应用程序在 Jboss 7.1.1 上运行。我有一个每分钟运行一次的调度程序,需要检查 DLQ 中是否有消息并在数据库中进行一些更新。

我编写了一个消息消费者,它侦听预定义的自定义 DLQ。问题是我可以看到自定义 DLQ 中有消息,但 consumer.receiveNoWait() 总是返回 null。

这里是创建消费者的代码:

/*this is running fine and creating the consumer*/
public DestinationHandlerImpl(ConnectionFactory connectionFactory,
    Destination destination, boolean useTransaction, int delMode,
    boolean isProducer) throws JMSException {
    connection = connectionFactory.createConnection();
    consumer = session.createConsumer(destination);
}

这是使用消息的代码(每分钟运行一次):

/*this always return null, event when there are messages in the queue*/
public <T extends BaseEvent> T recieveMessage()
        throws JMSException {

    Message message = consumer.receiveNoWait(); // ----> always return null!!!

    if (message != null && !(message instanceof ObjectMessage)) {
        throw new IllegalArgumentException(
                "message object has to be of type ObjectMessage");
    }

    // Extract the object from the message
    return message == null ? null : (T) ((ObjectMessage) message).getObject();

}

我使用了调试模式,我可以看到消费者目标属性设置为正确的队列,那么我做错了什么?

【问题讨论】:

    标签: java jakarta-ee jms jboss7.x message-queue


    【解决方案1】:

    找到了,我只需要在开始消费前添加connection.start()

    public <T extends BaseEvent> T recieveMessage()
        throws JMSException {
    
        connection.start(); // --->**added this line**
        Message message = consumer.receiveNoWait(); 
    
        if (message != null && !(message instanceof ObjectMessage)) {
            throw new IllegalArgumentException(
                "message object has to be of type ObjectMessage");
        }
    
        // Extract the object from the message
        return message == null ? null : (T) ((ObjectMessage) message).getObject();
    }
    

    【讨论】:

    • 我希望您不想每分钟都拨打start(),而是应该在第一次打开连接时拨打一次。
    • 我确保每次调度程序启动时都关闭连接。
    • 请问为什么?您是否关心打开连接的资源消耗?
    • 这实际上是很久以前设计的一个非常大的系统的一部分,我只是添加了一个使用系统机制的新适配器。
    • 谢谢,犯了同样的错误。奇怪,因为我使用相同的连接通过两个队列发送和接收,发送工作没有调用 connection.Start()
    【解决方案2】:

    即使使用connection.start(),我也遇到了这个问题!我的工作解决方案:

    使用receive(long timeout) 代替receiveNoWait()

    Obs.:1000 毫秒,因为在一个简单的测试用例中超时工作正常,但为了确保在生产中,我将其配置为 10000 毫秒。就我而言,在迭代消息时,当我收到null(没有更多消息)时我停止了,在最后一次调用中,receive(10000) 等待了整整 10 秒(显然)。我不得不使用异步方法来缓解这个性能问题。


    编辑:此外,根据实现 (jbm),它可能预取了一些消息(预选以供使用),这使得消息不可用,因为它们正在 传递 em> 状态。

    【讨论】:

    • 我似乎遇到了同样的问题。我真的不喜欢用超时调用接收,因为(根据定义)这是一个竞争条件。您对此了解更多吗?
    • @fool4jesus 抱歉,在我对那个案例的研究中找不到任何进一步的信息。实际上,以上对我来说真的很好。
    猜你喜欢
    • 1970-01-01
    • 2021-03-06
    • 1970-01-01
    • 2016-11-11
    • 1970-01-01
    • 2015-11-25
    • 2020-03-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多