简体   繁体   English

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

[英]JMS temporary queue discards first message

I'm sending JMS requests to a Weblogic 10.3 server through a named JMS queue, and receive a reply back through a temporary queue.我通过命名的 JMS 队列向 Weblogic 10.3 服务器发送 JMS 请求,并通过临时队列接收回复。

Client (barebone):客户端(准系统):

//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

Server MDB (message driven bean):服务器 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);
    }
}

The problem is that the very first server reply is often lost, That is, the replyConsumer.receive(5000) ends with timeout for every 4th-5th replyConsumer.问题是第一个服务器回复经常丢失,也就是说, replyConsumer.receive(5000)每第 4-5 个 replyConsumer 以超时结束。 When the consumer receives the first answer, then it continues to receive all the rest, so the problem is only with the first message send through the temporary queue after the temp queue has been created.当消费者收到第一个答案时,它会继续收到所有 rest,因此问题仅在于创建临时队列后通过临时队列发送的第一条消息。

My question: Do I have to set something special for the temporary queue in order it works from the very start after being created?我的问题:我是否必须为临时队列设置一些特殊的东西,以便它在创建后从一开始就可以工作? Or any other hint?或者还有什么提示?

Further info:更多信息:

  • When testing against my local development machine, the temp queues work without problem.在针对我的本地开发机器进行测试时,临时队列可以正常工作。 The messages are getting lost only when testing against our clustered Weblogic server.只有在针对我们的集群 Weblogic 服务器进行测试时,消息才会丢失。 However, I have switched off all cluster members but one instance.但是,我关闭了除一个实例之外的所有集群成员。
  • I have verified that the server successfully replies all the requests that the client sends (by counting the sent requests and sent replies).我已经验证服务器成功回复了客户端发送的所有请求(通过计算发送的请求和发送的回复)。 The server replies in the order of milliseconds, even for the lost replies.服务器以毫秒为单位进行回复,即使是丢失的回复也是如此。
  • When I replace the temporary queue with a regular named queue, the problem disappears.当我用常规命名队列替换临时队列时,问题就消失了。 So the problem doesn't seem (to me) to be in my code.所以问题似乎(对我来说)不在我的代码中。
  • I've also tried to modify expiration, persistency, delay etc. of the reply message, but without success.我也尝试过修改回复消息的到期时间、持久性、延迟等,但没有成功。 This way I excluded the scenario that the response arrives earlier than the client begins to read the queue, and then the message immediately expires not giving the client a chance to process it.这样我就排除了响应早于客户端开始读取队列,然后消息立即过期而不给客户端处理它的机会的情况。
  • Edit: Instead of the synchronous replyConsumer.receive(5000) I've also tried to use the asynchronous replyConsumer.setMessageListener(this) .编辑:我还尝试使用异步replyConsumer.setMessageListener(this)而不是同步replyConsumer.receive(5000) ) 。 The behaviour hasn't changed, first messages are still getting lost for temp queues.行为没有改变,临时队列的第一条消息仍然丢失。

Edit: It seems that there's something wrong with the Weblogic server (or cluster) I am using.编辑:我正在使用的 Weblogic 服务器(或集群)似乎有问题。 Because when I deployed the server application to another Weblogic cluster we have, everything began to work correctly?因为当我将服务器应用程序部署到我们拥有的另一个 Weblogic 集群时,一切都开始正常工作了吗? Both clusters should be configured identically - so where's a difference.两个集群的配置应该相同——所以区别在哪里。 It scares me that the Weblogic signals no error.令我害怕的是 Weblogic 没有发出错误信号。

Your problem seems to be that sometimes the server is receiving the publish and discarding it before your consumer has started receiving.您的问题似乎是有时服务器正在接收发布并在您的消费者开始接收之前丢弃它。

The way around it is to use the asynchronous receive (replyConsumer.setMessageListener) calls instead of the blocking call you currently have (replyConsumer.receive(5000)) and to add the call to the code with the rest of your consumer code.解决方法是使用异步接收 (replyConsumer.setMessageListener) 调用而不是您当前拥有的阻塞调用 (replyConsumer.receive(5000)),并将调用添加到您的消费者代码的 rest 代码中。

That way, you are already listening for replies before you send out the request.这样,您在发送请求之前就已经在收听回复。

Hope that helps.希望有所帮助。

Edit: Just read that you are using a temporary queue, so my first sentence is not correct.编辑:刚读到您正在使用临时队列,所以我的第一句话不正确。 However as an experiment try the rest of my response to see if it changes the behaviour you are seeing但是,作为实验,请尝试我的回复中的 rest,看看它是否会改变您所看到的行为

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM