我们使用 MSMQ 对发送到在 Windows Server 2012 上运行的内部服务总线的消息进行事务处理,并且在消息处理失败时遇到了问题。
服务的设置
服务
<endpoint address="net.msmq://localhost/private/quoteandbuy_transactions" binding="netMsmqBinding" bindingConfiguration="MsmqQuoteAndBuy" name="Msmq" contract="Soa.Net.EndPoints.IMessagingXmlProcessor" />
捆绑
<binding name="MsmqQuoteAndBuy" durable="true" exactlyOnce="true" maxRetryCycles="100" receiveErrorHandling="Move" receiveRetryCount="0" retryCycleDelay="01:00:00" useMsmqTracing="true" maxReceivedMessageSize="2147483647">
<readerQuotas maxStringContentLength="2147483647" />
<security mode="None">
<transport msmqAuthenticationMode="None" msmqProtectionLevel="None" />
<message clientCredentialType="None" />
</security>
</binding>
如您所见,我们每 1 小时运行一个周期,每条消息重试次数限制为 100 次。由于消息的 TTL 是 24 小时(默认),因此默认情况下永远不会实现这一点。
我们在 MSMQ 中的事务可能会由于第三方执行的过程而失败。消息被丢弃到重试子队列中。更多的进来,同样的事情发生。现在说,例如我们有 20 次失败。
因为它目前只有第一条消息(有时也是第二条?)将被重试,这很可能有相同的失败过程,所以我们再次不提交事务。
我希望所有达到重试周期时间跨度的消息都被移动到主队列以再次尝试,但这不会发生。顶部消息将继续阻塞,直到达到其 TTL 或最终成功。
是一种将队列行为设置为不阻塞和处理已达到重试时间跨度的所有消息的方法。
我们处于这样一种情况,如果说在 10 分钟内收到 20 条消息,如果它们都失败了,则只有第一条消息每小时重试一次,而其他 19 条则坐在那里,直到第一条消息达到 TTL,然后它们会被尝试和因为他们已经达到了 TTL,所以他们也会从重试队列中删除。
我知道消息传递是在 FIFO 的基础上工作的,并且在 vista 上的 MSMQ 之前,消息失败会阻塞其他消息,因此会阻塞重试消息队列。但这不是把问题转移到了重试子队列上吗?