所以我试图了解服务总线时序......尤其是锁的工作原理。人们可以选择手动调用 CompleteAsync,这就是我们正在做的事情。处理也可能需要一些时间。在这些情况下,我们要确保不会出现不必要的情况
MessageLockLostException
。
似乎有几个数字与之相关:
假设处理运行了大约 2 分钟,然后要么成功,要么崩溃(目前哪种情况都没关系)。假设这是正常情况,因此这意味着每条消息的处理大约需要 2 分钟。
而且,这确实是一个队列而不是一个主题。我们只有一个消费者异步处理消息,并将
MaxConcurrentCalls
设置为 100。我们将 OnMessageAsync
与 ReceiveMode.PeekLock
一起使用。
作为单个消费者,我现在应该如何设置才能稳健地处理所有消息?
我认为将锁定持续时间保留为 1 分钟就可以了,因为这是默认值,为了安全起见,将我的 AutoRenewTimeout 设置为 5 分钟,因为据我所知,这个值应该是处理消息所需的最长时间(至少根据这个答案)。性能对于这个系统来说并不重要,所以我有共鸣,因为将消息锁定一些不必要的 1、2 或 3 分钟并不是邪恶的,只要我们没有得到 LockedException,因为这些没有任何实际价值。
作为单个消费者,我现在应该如何设置才能稳健地处理所有消息?
除了
LockDuration
、MaxConcurrentCalls
、AutoRenewTimeout
和 AutoComplete
之外,您可能还想了解一些 Azure 服务总线客户端的配置。
例如,不要创建将
MaxConcurrentCalls
设置为 100 的单个客户端,而是创建多个客户端,并在它们之间分配总并发级别。请注意,您需要使用 different MessagingFactory
实例来创建这些客户端,以确保您有多个“管道”来接收消息。即便如此,横向扩展并拥有竞争性消费者比让单个消费者处理所有负载要好得多。
现在回到设置。如果您的正常处理时间是 2 分钟,最好将实体上的
MaxLockDuration
设置为这个时间而不是 1 分钟。这将消除对代理的不必要的锁定扩展调用并消除MessageLockLostException
。
此外,请记住,
AutoRenewTimeout
操作是基于客户,而不是经纪商,因此无法保证。即使AutoRenewTimeout
时间尚未过去,你也会遇到锁定丢失的情况。
AutoRenewTimeout
应始终设置为比 MaxLockDuration
长,因为让它们相等会适得其反。让它比MaxLockDuration
稍大一些,因为这是客户的“保险”,当处理时间超过MaxLockDuration
时,消息锁定不会丢失。从本质上讲,让这两个相等就禁用了这种后备。