You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否修改/删除ServiceBusReceivedMessage应用属性?需重置重试计数器

解决方案

由于ServiceBusReceivedMessage的ApplicationProperties是只读属性,无法直接修改原消息的属性,要实现死信消息不带retryCounter或重置其值为0,你需要通过创建新消息并手动发送到死信队列的方式来实现,具体步骤如下:

  1. 在达到最大重试次数时,创建一个新的ServiceBusMessage实例,复制原消息的所有内容
  2. 移除新消息中的RetryCount属性(或重置为0)
  3. 手动将新消息发送到死信队列,并添加标准死信属性(如死信原因、错误描述)
  4. 标记原消息为完成,避免重复处理

修改后的代码示例

catch (Exception ex) when (ex.Message.Contains("Not Found"))
{
    int retries = 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 - 处理死信消息,移除/重置RetryCount
    else
    {
        log.LogError("Transaction number {transaction} has reached max number of 404 retries", parsedMessage.Transaction);
        
        // 1. 创建新消息,复制原消息内容
        var deadLetterMsg = new ServiceBusMessage(message);
        
        // 2. 移除RetryCount属性,如需重置为0则替换为Add操作
        if (deadLetterMsg.ApplicationProperties.ContainsKey("RetryCount"))
        {
            deadLetterMsg.ApplicationProperties.Remove("RetryCount");
            // 若要重置为0,取消下面注释
            // deadLetterMsg.ApplicationProperties.Add("RetryCount", 0);
        }
        
        // 3. 添加标准死信属性,和系统自动死信格式对齐
        deadLetterMsg.ApplicationProperties.Add("DeadLetterReason", "Max retry count reached");
        deadLetterMsg.ApplicationProperties.Add("DeadLetterErrorDescription", ex.Message);
        
        // 4. 获取死信队列路径(根据你的实际队列/主题订阅调整)
        // 队列的死信路径:$"{队列名称}/$DeadLetterQueue"
        // 主题订阅的死信路径:$"{主题名称}/subscriptions/{订阅名称}/$DeadLetterQueue"
        var deadLetterQueuePath = $"{_config.QueueName}/$DeadLetterQueue";
        using var deadLetterSender = _serviceBusClient.CreateSender(deadLetterQueuePath);
        
        // 发送到死信队列
        await deadLetterSender.SendMessageAsync(deadLetterMsg);
        
        // 5. 完成原消息,避免重复处理
        await _messageReceiver.CompleteMessageAsync(message, messageReceiver);
    }
}

注意事项

  • 确保已在依赖注入中正确配置ServiceBusClient实例
  • 根据你使用的是队列还是主题订阅,调整死信队列的路径格式
  • 手动发送的死信消息会保留原消息的核心内容,同时移除/重置了RetryCount属性,且添加了符合规范的死信元数据

内容的提问来源于stack exchange,提问作者Chris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 04:42:13