Azure Service Bus队列。我多次收到同样的消息

时间:2013-07-22 12:08:20

标签: .net azure azure-servicebus-queues

我调用client.Send(brokeredMessage);一次,但是我多次收到该消息。对于句柄队列,我使用此代码

private static void HandleQueue(string queueName, MessageHandler messageHandler)
        {
            // Create the queue if it does not exist already
            string connectionString =
                Configuration.GetConnectionString("Microsoft.ServiceBus.ConnectionString",false);

            var namespaceManager =
                NamespaceManager.CreateFromConnectionString(connectionString);

            if (!namespaceManager.QueueExists(queueName))
            {
                namespaceManager.CreateQueue(queueName);
            }

            QueueClient client =
                QueueClient.CreateFromConnectionString(connectionString, queueName);

            while (true)
            {
                BrokeredMessage message = client.Receive();

                if (message != null)
                {
                    try
                    {    
                        messageHandler(message);

                        // Remove message from queue
                        message.Complete();
                    }
                    catch (Exception)
                    {
                        // Indicate a problem, unlock message in queue
                        message.Abandon();
                    }
                }
            }
        }

问题是如果执行BrokeredMessage message = client.Receive();需要很长时间,则会多次调用messageHandler(message);并返回相同的消息。我该如何解决?

3 个答案:

答案 0 :(得分:11)

在您处理邮件时,邮件会被解锁。设置邮件锁定超时的正确位置位于QueueDescription http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.queuedescription.lockduration.aspx

此处允许的最长时间为5分钟,因此如果您需要处理消息的时间更长,则可以在消息上调用RenewLock以继续让其对其他消费者不可见。你是正确的,在你完成处理之前调用Complete是不可取的,就好像你处理崩溃那样你就不会再收到消息了。

当消息从队列中显示给消费者时,上面提到的BrokeredMessage.ScheduledEnqueueTimeUtc属性用于“延迟”。假设您在第1天发送消息并将预定时间设置为第2天,则Recieve呼叫将不会在第2天之前返回消息。

答案 1 :(得分:1)

你应该做一些事情:

  1. 在While(true)循环中引入睡眠时间。可以说,Thread.Sleep(30000);
  2. 检索邮件内容并将邮件标记为已完成。然后将检索到的内容传递给消息处理程序而不是消息本身。等待“messagehanfler”的完成并不是一个好习惯。
  3. 如果在处理过程中您的消息处理程序中发生错误,请使用相同内容对另一个代理消息进行排队。
  4. 处理有害信息。检查每个代理邮件的发送计数,如果发送次数超过n次,则删除该邮件,假设为5次。
  5. 希望它有所帮助!

答案 2 :(得分:1)

如果在允许的时间内没有处理过你的消息,那么你的消息就会回到队列中(根据你的描述,只有当messageHandler运行很长时间才会发生)。

听起来您希望增加邮件的可见性超时,这样他们就不会那么快地回到队列中。使用ServiceBus,这意味着预先计算消息重新出现的时间(如果尚未完成)

http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.brokeredmessage.scheduledenqueuetimeutc.aspx