ServiceBus 消息版本控制的最佳实践

Jak*_*ner 5 c# version servicebus azureservicebus

我正在建立一个系统,我们将在 ServiceBus 主题上的多个内部服务之间传输消息。消息将保存序列化的对象。模型对象被定义为相当复杂的类树。这意味着在代码中维护模型结构的双重版本是不切实际的。

我们预计模型结构会发生变化,因此我将模型版本作为代理消息的属性公开。

当我们需要升级模型版本时,处理过渡的最佳方法是什么?

我不认为我们真的需要支持两个并行模型版本。但我担心我们在过渡期间不会丢失信息。我认为首先升级发送服务并让所有订阅者继续处理消息是一个很好的策略。当之前版本的所有消息都处理完毕后,就到了订阅服务升级的时候了。

跳过侦听服务当前未处理的新版本消息的最佳机制是什么?

  1. 我知道我可以回到老方法,通过使用 json 或 xml 模式来定义并行模型版本,从而使监听服务能够处理并行版本。但这会很麻烦,所以我真的想避免这种情况。

  2. 我注意到 BrokeredMessage 有一个 Defer 方法。那会有用吗?它看起来很有希望,直到我意识到消息将从实时队列“移动”到一个单独的状态,需要通过按键引用它们来拉取它们。不实用。

  3. 是否可以通过修改发送时间来推迟消息?几分钟就可以了。如果到那时相同的服务仍在运行,则可以再次推迟。(如果有工作代码示例,我们将不胜感激!)

  4. 我需要根据型号版本创建单独的订阅吗?到目前为止,我们允许不同的消息类型在同一主题上传播,因此需要进行一些重新设计。

McG*_*Gaz 1

我一直在研究类似的东西,但尚未实现它,因此无法提供完整的指导,但要回答您关于#3的问题...我有一些消息,其中有一个标志可以重新排队消息以再次运行,例如让进程每 5 分钟运行一次。

因此,在此过程中,我从 BrokeredMessage 中提取对象:

  var myObject = receivedMessage.GetBody<MyModel>();  
Run Code Online (Sandbox Code Playgroud)

然后,我完成该消息以将其从队列中删除,并基于该对象创建一个新的 BrokeredMessage,然后您可以将 ScheduledEnqueueTimeUtc 字段设置为将来的某个值。

 BrokeredMessage brokeredMsg = new BrokeredMessage(myObject);
 brokeredMsg.ScheduledEnqueueTimeUtc = DateTime.UtcNow.AddMinutes(5);
 Client.Send(brokeredMsg);
Run Code Online (Sandbox Code Playgroud)

因此,如果您只想一次处理一个型号版本,您可以为您的型号分配一个版本号,并向处理器中编码一些内容以查找特定型号。如果模型更高,则将其重新排队以供将来使用(直到您更新了代码)。如果它较低(丢失消息),则可能需要进行一些异常处理。