9

Azure 服务总线出现间歇性问题。偶尔,在总线上放置消息会导致以下异常:

类型:无效操作异常

MESSAGE:无法执行操作,因为代理消息“723eab13dab34351a78bb687d0923b89”已被消费。请使用新的 BrokeredMessage 实例进行操作。

堆栈跟踪

at Microsoft.ServiceBus.Messaging.MessagingUtilities.ValidateAndSetConsumedMessages(IEnumerable`1 messages)
at Microsoft.ServiceBus.Messaging.MessageSender.Send(TrackingContext trackingContext, IEnumerable`1 messages, TimeSpan timeout)
at Microsoft.Practices.TransientFaultHandling.RetryPolicy.<>c__DisplayClass1.<ExecuteAction>b__0()
at Microsoft.Practices.TransientFaultHandling.RetryPolicy.ExecuteAction[TResult](Func`1 func)
at IQ.IR.Core.ServiceBus.AzureBus`1.Enqueue(T message) in c:\BuildAgent\work\cc0c51104c02a4e9\IQ.IR.Core\ServiceBus\AzureBus.cs:line 69
...Rest of stacktrace snipped as it's within my app

AzureBus 的违规代码是:

public void Enqueue(T message)
{
    using (var brokeredMessage = new BrokeredMessage(message) { Label = message.GetType().FullName, TimeToLive = _timeToLive })
    {
        _retryPolicy.ExecuteAction(() => _sender.Send(brokeredMessage));
    }
}

传入的 T 消息是

[Serializable]
public class ValidationMessage
{
    public string ValidationToken { get; set;}
}

_retryPolicy 是一个

RetryPolicy<ServiceBusTransientErrorDetectionStrategy>

_timeToLive 是 12 小时的时间跨度

有任何想法吗?

4

4 回答 4

6

.... 并补充 Abhishek 的回答:现在您需要为每次重试构建一个新的 BrokeredMessage,因此您的重试策略范围需要更上一层。请注意,如果您放入一个流,我们将在代理消息中按原样使用该流并将其直接拉到线路上,因此您需要提前制作流的副本以进行重试循环。

于 2012-09-07T16:22:50.823 回答
5

该错误表示消息“已发送”,但过程中发生错误。不幸的是,没有简单的方法可以通过检查消息来了解这一点,并且消息不能再次被重用,因为它被认为是已消耗的。我们正在进行一些改进,例如允许您查询此类消息的状态并抛出 MessagingException 而不是 InvalidOperation。最后,克隆消息的能力将有助于更容易地从此类故障中恢复。

于 2012-09-07T06:13:19.230 回答
2

我最近遇到了这个问题并发现了另一个原因:如果您正在构建一个 BrokeredMessage 并在使用 MessageSender 发送它之前设置一个断点,并检查 Message 上的属性,它将尝试访问队列并抛出此异常。简单地先发送消息而不在 IDE 中检查其属性不会导致此问题。

于 2018-08-23T13:20:35.910 回答
1

即使出现错误,是否可能已发送消息?在这种情况下尝试重试之前消息是否应该是幂等的?

于 2012-09-10T19:54:46.163 回答