我需要创建一个高吞吐量的ServiceBus队列客户端,该客户端每秒可以处理1000条消息。我设法实现这一目标的唯一方法是结合使用ReceiveMode.ReceiveAndDelete
和PrefetchCount
。
var client = new QueueClient(connectionString, queueName, ReceiveMode.ReceiveAndDelete);
client.PrefetchCount = 1000;
client.RegisterMessageHandler(ProcessMessagesAsync, new MessageHandlerOptions());
await Task.Delay(10000); // wait for 10s while some messages are processed
await client.CloseAsync();
可靠性不是很关键,因此如果我的应用程序崩溃,我可以承受丢失消息的负担。但是,我想避免在正常关机期间丢失消息,例如上面的CloseAsync
调用。我特别希望避免丢失驻留在本地缓存中的数百条预取消息。有没有办法让客户端等到预取的消息处理完毕后,却停止接收新的消息?
答案 0 :(得分:0)
我没有找到合适的解决方法。它似乎是QueueClient
设计中的固有限制。但是,我发现MessageReceiver
提供了same functionality以及消息的批处理完成功能,从而可以可靠地消耗大量消息(大约500 msg / s)。
var messageReceiver = new MessageReceiver(
connectionString,
entityPath,
ReceiveMode.PeekLock,
prefetchCount: 1000);
var processedLockTokens = new List<string>();
while (true)
{
var messages = await messageReceiver.ReceiveAsync(maxMessageCount: 1000, operationTimeout: TimeSpan.FromSeconds(5));
if (messages == null)
continue;
try
{
foreach (var message in messages)
{
// Process message.
processedLockTokens.Add(message.SystemProperties.LockToken);
if (isCancellationRequested)
return;
}
}
finally
{
if (processedLockTokens.Any())
{
await messageReceiver.CompleteAsync(processedLockTokens);
processedLockTokens.Clear();
}
}
}