可以从 ServiceBusReceivedMessage 中更新/删除应用程序属性吗?

问题描述 投票:0回答:1

我有一个处理销售交易的 ServiceBusTrigger 方法。如果在数据库中找不到事务并返回 404,我将复制服务总线消息并在应用程序属性中添加/增加 retryCounter。当达到最大重试次数时,我将其写入死信。

我的问题是,我需要一种方法来从 serviceBusReceived 消息中删除 retryCounter,或者能够将其设置回零,以便可以重新提交消息。

这是我目前的逻辑。

` catch (Exception ex) when (ex.Message.Contains("Not Found")) { 整数重试 = 0;

            var parsedMessage = _messageReceiver.ParseServiceBusMessage(message);
            
            // create new sb message and retrieve retry count
            var newMessage = new ServiceBusMessage(message);
            newMessage.ApplicationProperties.TryGetValue("RetryCount", out object retry);
            
            if (retry != null)
                retries = Convert.ToInt32(retry);
            
            // retry less than max count - increment count, submit new msg to service bus, complete previous sb message
            if (retries < _config.MaxRetryCount)
            {
                var msgSuffix = DateTime.Now.ToString("yyyy-MM-dd H:mm:ss.FFFFFF");
                newMessage.MessageId = $"{parsedMessage.Transaction} {msgSuffix}";

                if (!newMessage.ApplicationProperties.ContainsKey("RetryCount"))
                    newMessage.ApplicationProperties.Add("RetryCount", (retries + 1).ToString());
                else
                {
                    newMessage.ApplicationProperties.Remove("RetryCount");
                    newMessage.ApplicationProperties.Add("RetryCount", (retries + 1).ToString());
                }

                newMessage.ScheduledEnqueueTime = DateTime.UtcNow.AddSeconds(_config.HoldServiceBusMsgMinutes);

                await outputEvents.AddAsync(newMessage);
                log.LogInformation("Transaction not found. Resubmitted to service bus {transaction}", parsedMessage.Transaction);

                await _messageReceiver.CompleteMessageAsync(message, messageReceiver);
            }
            // max retries reached - deadletter the service bus message
            else
            {
                log.LogError("Transaction number {transaction} has reached max number of 404 retries", parsedMessage.Transaction);
                await _messageReceiver.DeadletterMessageAsync(message, messageReceiver, ex);
            }
        }

`

我在ServiceBusReceived.ApplicationProperties中寻找Remove()方法,或者寻找更新属性的方法,但我相信它们是只读的。有没有另一种方法可以让消息在没有计数器的情况下变成死信,或者至少更新为零?谢谢您的任何建议。

c# azure azureservicebus
1个回答
0
投票

服务总线消息对于消费者来说是不可变的。 发布后,消息唯一可能发生的更改是代理拥有的字段,例如LockedUntil。 每次根据当前代理状态读取消息时,都会动态填充这些内容。

因此,无法按照您想要的方式管理重试计数应用程序属性 - 除非您愿意克隆消息并发布具有更新值的副本。

对于这种特定场景,您可能需要考虑使用 DeliveryCount,它是代理拥有的属性,每次在显式放弃或由于锁定过期后收到消息时,该属性都会增加 1。

事实上,如果您的目标是重试多次后出现死信,服务总线可以通过“最大交付计数”设置隐式地为您管理此操作。 您的应用程序只需决定是在成功时完成还是在失败时放弃。 更多讨论可以在将消息移至 DLQ 中找到。

© www.soinside.com 2019 - 2024. All rights reserved.