具有多个订阅者的Azure ServiceBus主题-重复消息
我有一个名为“IntegrationEvent”的Azure ServiceBus主题,其中一个订阅名为“TestSubscription”。我向该订阅注册了两个订阅者,我拥有有竞争力的消费者 在两个订阅者中都处理大量消息。我需要做什么来改变这种情况不再发生?我认为每封邮件应该只由一个订阅者处理 发件人:具有多个订阅者的Azure ServiceBus主题-重复消息,azure,azureservicebus,azure-servicebus-topics,azure-servicebus-subscriptions,Azure,Azureservicebus,Azure Servicebus Topics,Azure Servicebus Subscriptions,我有一个名为“IntegrationEvent”的Azure ServiceBus主题,其中一个订阅名为“TestSubscription”。我向该订阅注册了两个订阅者,我拥有有竞争力的消费者 在两个订阅者中都处理大量消息。我需要做什么来改变这种情况不再发生?我认为每封邮件应该只由一个订阅者处理 发件人: class Program { static async Task Main(string[] args) { await SendMessageAsync()
class Program
{
static async Task Main(string[] args)
{
await SendMessageAsync();
}
private static async Task SendMessageAsync()
{
var sendClient = new TopicClient("ConnectionString");
var testBlock = new ActionBlock<string>(
async id =>
{
string jsonMessage = JsonConvert.SerializeObject(id);
byte[] body = Encoding.UTF8.GetBytes(jsonMessage);
var messageToSend = new Message(body)
{
CorrelationId = id,
};
await sendClient.SendAsync(messageToSend);
}, new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism = 25
});
for (int i = 0; i < 10000; i++)
{
testBlock.Post(Guid.NewGuid().ToString());
}
testBlock.Complete();
await testBlock.Completion;
}
}
在尝试任何事情之前,了解订阅的工作原理非常重要。确实是这样。具体来说,这会影响订阅将接收的内容
现在,您的代码已设置为接收所有消息(全部捕获规则)。一旦您使用SQL或关联过滤器创建了更具体的规则,您将能够控制每个订阅将接收到的内容。我不久前写了一篇文章,其中包含了一些信息。谢谢肖恩,但你不是在订阅基础上筛选的吗?我只有一个订阅必须覆盖除几个消费者以外的所有消费者。如果我向我的单个订阅注册了两个消费者,那么两个消费者都会处理两条消息。我不明白。如果一条消息没有按时完成或出现错误,它可能会被多个消费者处理。检查DeliveryCount系统属性的值以确认。好的,谢谢,我检查过了,但我无法再复制。昨天的每一次跑步都有重复,今天它的效果如预期。。。
class Program
{
static SubscriptionClient subscriptionClient;
static async Task Main(string[] args)
{
var builder = new ServiceBusConnectionStringBuilder("ConnectionString");
if (string.IsNullOrWhiteSpace(builder.EntityPath))
{
builder.EntityPath = "IntegrationEvent";
}
subscriptionClient = new SubscriptionClient(builder, "TestSubscription");
await subscriptionClient.RemoveRuleAsync(RuleDescription.DefaultRuleName);
await subscriptionClient.AddRuleAsync(new RuleDescription(RuleDescription.DefaultRuleName, new TrueFilter()));
ListenForMessages();
Console.Read();
}
protected static void ListenForMessages()
{
var options = new MessageHandlerOptions(ExceptionReceivedHandler)
{
AutoComplete = false,
MaxConcurrentCalls = 10
};
subscriptionClient.RegisterMessageHandler(ReceiveMessageAsync, options);
}
private static Task ExceptionReceivedHandler(ExceptionReceivedEventArgs arg)
{
return Task.CompletedTask;
}
private static async Task ReceiveMessageAsync(Message arg1, CancellationToken arg2)
{
string integrationEvent = Encoding.UTF8.GetString(arg1.Body);
Console.WriteLine($"{ arg1.MessageId}, { arg1.CorrelationId}, {integrationEvent}");
await subscriptionClient.CompleteAsync(arg1.SystemProperties.LockToken);
}
}