当前位置: 首页 > 知识库问答 >
问题:

JMS临时队列丢弃第一条消息

史修谨
2023-03-14

我通过命名的JMS队列将JMS请求发送到Weblogic 10.3服务器,并通过临时队列接收回复。

客户(裸体):

//init
Destination replyQueue = session.createTemporaryQueue();
replyConsumer = session.createConsumer(replyQueue);
...
//loop
TextMessage requestMessage = session.createTextMessage();
requestMessage.setText("Some request")
requestMessage.setJMSReplyTo(replyQueue);
requestProducer.send(requestMessage);
Message msg = replyConsumer.receive(5000);
if (msg instanceof TextMessage) {
    ...
} else { ... }
//loop end

服务器MDB(消息驱动bean):

public void onMessage(Message msg) {
    if (msg instanceof TextMessage) {
        ...
        TextMessage replyMessage = jmsSession.createTextMessage();
        replyMessage.setText("Some response");
        replyMessage.setJMSCorrelationID(msg.getJMSCorrelationID());
        replyProducer.send(replyMessage);
    }
}

问题是第一个服务器回复经常丢失!也就是说,ReplyConsumer.receive(5000)每4-5个回复都以超时结束。当消费者收到第一个答案时,它将继续收到所有剩余的答案,所以问题只出在临时队列创建后通过临时队列发送的第一条消息上。

我的问题是:我是否必须为临时队列设置一些特殊的设置,以便它在创建后从一开始就工作?或者其他任何暗示?

更多信息:

  • 在本地开发机器上测试时,临时队列没有问题。只有在群集的Weblogic服务器上测试时,消息才会丢失。但是,除了一个实例,我已经关闭了所有群集成员。
  • 我已经验证了服务器成功回复了客户端发送的所有请求(通过计数发送的请求和发送的回复),服务器以毫秒的顺序回复,即使是丢失的回复。
  • 当我用常规命名队列替换临时队列时,问题就消失了!所以问题似乎不在我的代码中。
  • 我也尝试过修改回复消息的过期、持久、延迟等,但没有成功。这样我就排除了响应到达早于客户端开始读取队列的情况,然后消息立即过期,客户端没有机会处理它。
  • 编辑:我也尝试过使用异步ReplyConsumer.setMessageListener(this),而不是同步onsumer.receive(5000)。行为没有改变,临时队列中的第一条消息仍然丢失。

编辑:我使用的Weblogic服务器(或集群)似乎有问题。因为当我将服务器应用程序部署到另一个Weblogic集群时,一切都开始正常工作了!这两个集群的配置应该相同——那么有什么不同呢?Weblogic没有发出错误信号,这让我很害怕。

共有1个答案

赵佐
2023-03-14

您的问题似乎是,有时服务器正在接收发布,并在您的消费者开始接收之前将其丢弃。

绕过它的方法是使用异步接收(复制onsumer.setMessageListener)调用,而不是当前的阻塞调用(复制onsumer.receive(5000)),并将调用与其他消费者代码一起添加到代码中。

这样,在发出请求之前,您已经在监听回复了。

希望有帮助。

编辑:只是读到你正在使用一个临时队列,所以我的第一句话不正确。然而,作为一个实验,尝试我的其余反应,看看它是否会改变你所看到的行为

 类似资料:
  • 我正在尝试从 kafka 主题中获取消息,并看到如果我将 auto.commit.reset 策略设置为“最早”,则所有消息都会得到正确处理。但是,如果设置为“最新”,则第一条消息将丢失,其余消息将得到正确处理。如果我在这里错过了什么,任何人都可以帮忙吗?

  • 我有一个应用程序,我想使用队列A中的消息,但是如果队列A是空的,我希望它使用队列B中的消息,而不是闲置。我只希望它一次处理一条消息,如果使用者正忙于处理一条消息(来自任一队列),那么其他挂起的消息(在任一队列中)应该保留在他们的队列中,直到使用者再次空闲(这给其他使用者一个机会来处理新的消息)。 例如,如果一条消息在使用者空闲(等待)时到达队列a或队列B,那么使用者就会拾取它。如果在使用者当前正在

  • 你知道这里发生了什么吗?可以恢复消息和队列吗?如何使用ActiveMQ Artemis数据?所有队列/消息都丢失了。只有dlq/expiryqueue。 我们必须更改配置。所以我们开始更新从机。 为了将故障转移到从服务器以修复主服务器,我们执行了@16:32 在Master上有一些警告,但不多。 在从服务器上,我们可以看到一些超时和连接失败。不确定Slave是否接管了队列并且工作正常。 @16:4

  • 我在Weblogic 12c上部署了一个MDB,它从JMS队列(UDQ)读取消息。MDB正在读取消息,但它没有从JMS队列中删除,这导致消息被重复读取。所以,我想知道MDB何时确认JMS队列它成功读取了消息,并且队列应该删除该消息。

  • 问题内容: 有一条消息(文本),我肯定知道其格式和内容。 目前,已经实现了Java类,该类从文件中解析并读取此消息。 在现实世界中,此消息将来自消息队列。 现在,我应该在本地PC上模拟,模拟或生成Message Queue,以进行测试。 Java规范(java jms ): 关于此规范,我需要 JMS provider 。 JMS客户端 -这是我的类,它读取消息。 消息 本身,我知道。 那么问题是

  • 因此,我使用Spring integration链接JMS和ActiveMQ,如下所示:- 如何使其工作,以便发送到此队列并从中接收消息?请帮忙。