.NET 5中获取Azure Service Bus队列消息ID的并发问题解决方案问询
解决方案
你可以通过两种常用方案解决这个问题,按需选择即可:
方案1:附加自定义唯一标识+过滤接收
在发送消息前为消息添加自定义的唯一标识属性,接收时通过标识匹配确认是自己发送的消息:
string connectionString = "<connection_string>"; string queueName = "<queue_name>"; await using var client = new ServiceBusClient(connectionString); ServiceBusSender sender = client.CreateSender(queueName); ServiceBusMessage message = new ServiceBusMessage("Hello world!"); // 本地生成唯一标识附加到消息的自定义属性中 string customUniqueId = Guid.NewGuid().ToString(); message.ApplicationProperties.Add("CustomSenderId", customUniqueId); await sender.SendMessageAsync(message); ServiceBusReceiver receiver = client.CreateReceiver(queueName); ServiceBusReceivedMessage receivedMessage = null; // 循环拉取消息匹配自定义标识,匹配成功才终止 while (receivedMessage == null) { var tempMsg = await receiver.ReceiveMessageAsync(TimeSpan.FromSeconds(5)); if (tempMsg != null && tempMsg.ApplicationProperties.TryGetValue("CustomSenderId", out var idObj) && idObj.ToString() == customUniqueId) { receivedMessage = tempMsg; // 匹配成功后完成消息,避免被其他消费者拉取 await receiver.CompleteMessageAsync(receivedMessage); } else if(tempMsg != null) { // 不是自己的消息就放弃,让它回到队列供其他消费者处理 await receiver.AbandonMessageAsync(tempMsg); } } string targetId = receivedMessage.Id;
如果队列消息量大,你还可以提前为队列创建过滤规则,直接让服务端只返回匹配自定义标识的消息,减少本地匹配的性能损耗。
方案2:使用Service Bus会话功能
如果你的队列已经开启了会话支持,直接指定唯一的SessionId发送消息,再按SessionId接收即可精准拿到自己发送的消息,不需要手动匹配:
// 发送侧 string sessionId = Guid.NewGuid().ToString(); ServiceBusMessage message = new ServiceBusMessage("Hello world!") { SessionId = sessionId }; await sender.SendMessageAsync(message); // 接收侧:按指定SessionId创建接收器,只会收到对应会话的消息 var sessionReceiver = await client.AcceptSessionAsync(sessionId, queueName); var receivedMessage = await sessionReceiver.ReceiveMessageAsync(); await sessionReceiver.CompleteMessageAsync(receivedMessage); string targetId = receivedMessage.Id;
这个方案适合需要严格隔离不同发送者消息的场景,性能比方案1更高,但是要求队列提前开启会话功能。
内容的提问来源于stack exchange,提问作者Emmanouil Dagdilelis
相关产品推荐
相关产品推荐

