当前使用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");
使用上面的代码,如果我发送4条消息,那么在第一次运行时轮询我得到第一条消息。在第二轮比赛中,我得到了另外一部分。我期待在同一时间获得全部4分。它似乎总是在第一次民意调查中返回一个单数值,然后在随后的民意调查中返回其余值。 (与3和5的结果相同,我在第二次尝试时发送n条消息中的n-1条,第一次尝试时发送1条消息)。
如果我要接收0条消息,则操作需要约30-60秒才能获得messageList(具有0计数)。我需要立即返回。
如果我将代码更改为IEnumerable<BrokeredMessage> messageList = client.ReceiveBatch(100, new Timespan(0,0,0));
,那么问题#2就会消失,因为问题1仍然存在,我必须两次调用代码才能获取所有消息。
我假设问题#2是由于我在#3中覆盖的默认超时值(尽管我发现如果有消息,它会立即响应而不等待默认时间,这令人困惑)。我不知道为什么我从未在单个ReceiveBatch中收到全部消息。
答案 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的内存缓存中的某种损坏/错误。