Azure Service Bus ReceiveBatch()的奇怪行为

时间:2015-08-11 18:49:17

标签: c# azure azureservicebus

当前使用Azure Service Bus主题并遇到使用ReceiveBatch方法接收我的消息的问题。问题是预期的结果实际上并不是我得到的结果。以下是基本代码设置,用例如下:

    SubscriptionClient client = SubscriptionClient.CreateFromConnectionString(connectionString, convoTopic, subName);

    IEnumerable<BrokeredMessage> messageList = client.ReceiveBatch(100);
        foreach (BrokeredMessage message in messageList)
        {
            try
            {
                Console.WriteLine(message.GetBody<string>() + message.MessageId);

                message.Complete();
            }
            catch (Exception ex)
            {
                message.Abandon();
            }
        }

    client.Close();
    MessageBox.Show("Done");
  1. 使用上面的代码,如果我发送4条消息,那么在第一次运行时轮询我得到第一条消息。在第二轮比赛中,我得到了另外一部分。我期待在同一时间获得全部4分。它似乎总是在第一次民意调查中返回一个单数值,然后在随后的民意调查中返回其余值。 (与3和5的结果相同,我在第二次尝试时发送n条消息中的n-1条,第一次尝试时发送1条消息)。

  2. 如果我要接收0条消息,则操作需要约30-60秒才能获得messageList(具有0计数)。我需要立即返回。

  3. 如果我将代码更改为IEnumerable<BrokeredMessage> messageList = client.ReceiveBatch(100, new Timespan(0,0,0));,那么问题#2就会消失,因为问题1仍然存在,我必须两次调用代码才能获取所有消息。

  4. 我假设问题#2是由于我在#3中覆盖的默认超时值(尽管我发现如果有消息,它会立即响应而不等待默认时间,这令人困惑)。我不知道为什么我从未在单个ReceiveBatch中收到全部消息。

2 个答案:

答案 0 :(得分:1)

我遇到与ASB队列类似的问题。我发现我可以通过在接收批处理之前增加客户端上的PrefetchCount来稍微减轻它:

SubscriptionClient client = SubscriptionClient.CreateFromConnectionString(connectionString, convoTopic, subName);

client.PrefetchCount = 100;

IEnumerable<BrokeredMessage> messageList = client.ReceiveBatch(100);

从Azure Service Bus Best Practices for Performance Improvements Using Service Bus Brokered Messaging

  

预取使队列或订阅客户端在执行接收操作时从服务加载其他消息。

     

...

     

当使用60秒的默认锁定到期时,一个很好的值   SubscriptionClient.PrefetchCount是工厂所有接收器的最大处理速率的20倍。例如,工厂创建3个接收器,每个接收器每秒最多可处理10个消息。预取计数不应超过20 * 3 * 10 = 600.

     

...

     

预取消息会增加队列或订阅的总吞吐量,因为它会减少消息操作的总数或往返次数。但是,获取第一条消息需要更长时间(由于消息大小增加)。接收预取消息的速度会更快,因为客户端已经下载了这些消息。

答案 1 :(得分:0)

这个难题只需要几个部分。即使在启用批处理和禁用分区之后,我仍然无法使其工作 - 我仍然需要进行两次ReceiveBatch调用。但我找到了:

  • 重新启动Service Bus服务(我正在使用Service Server for Windows Server)为我解决了这个问题。
  • 执行单个RecieveBatch并且不执行任何操作(让消息锁定到期)然后执行另一个ReceiveBatch导致所有消息同时通过。 (对所有消息执行初始ReceiveBatch并调用Abandon不会导致该行为。)

所以它似乎是Service Bus的内存缓存中的某种损坏/错误。