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

C# ServiceBus消息版本控制的最佳实践,c#,version,azureservicebus,servicebus,C#,Version,Azureservicebus,Servicebus,我正在建立一个系统,在该系统中,我们将在ServiceBus主题的多个内部服务之间传输消息。这些消息将保存序列化对象。模型对象被定义为相当复杂的类树。这意味着在代码中维护模型结构的duplet版本是不实际的 我们希望模型结构会发生变化,因此我将模型版本作为代理消息的属性公开 当我们需要升级模型版本时,处理转换的最佳方法是什么 我不认为我们真的需要支持两个并行模型版本。但我担心的是,我们不会在过渡期间泄露信息。我认为首先升级发送服务并让所有订户继续处理消息是一个好策略。当处理了以前版本的所有消息后

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

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

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

我不认为我们真的需要支持两个并行模型版本。但我担心的是,我们不会在过渡期间泄露信息。我认为首先升级发送服务并让所有订户继续处理消息是一个好策略。当处理了以前版本的所有消息后,就可以升级订阅服务了

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

  • 我知道我可以回到老派,通过使用json或xml模式定义并行模型版本,从而使侦听服务能够处理并行版本。但那会很麻烦,所以我真的想避免

  • 我注意到BrokeredMessage有一个延迟方法。那有用吗?在我意识到消息将从实时队列“移动”到一个单独的状态之前,它看起来很有希望,在这个状态下,它们需要通过键引用来提取。不实际

  • 是否可以通过修改传递时间来推迟邮件?几分钟就可以了。如果到那时同一服务仍在运行,则可以再次推迟。(请提供一个工作代码示例!)

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


  • 根据经验:在实时系统上升级是困难的。将系统停机风险降至最低的最简单选项是:

    • 将下一消息版本支持添加到当前代码库
    • 同时运行两个消息版本
    • 确保支持所有版本,并且系统运行无问题
    • 删除以前的版本

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

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

      var myObject = receivedMessage.GetBody<MyModel>();  
    

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

    对消息使用自定义
    MessageProperty
    ,例如
    Version

    在SB主题下-创建只接受新版本消息的新订阅(使用规则),并修改现有订阅以不接受新版本消息

    然后您可以升级发件人-新邮件将仅存储在新的“临时”订阅中

    然后,升级侦听器,更改订阅规则(从“主”订阅中删除版本规则,禁用临时订阅上的接收)

    现在你有选择了:

    • 使用任何工具从临时订阅中读取消息并将它们写回主题-它们将到达升级的侦听器
    • 临时启动另一个侦听器,该侦听器将读取临时订阅并处理其中的所有消息
    • 其他方式,特定于您的体系结构
     BrokeredMessage brokeredMsg = new BrokeredMessage(myObject);
     brokeredMsg.ScheduledEnqueueTimeUtc = DateTime.UtcNow.AddMinutes(5);
     Client.Send(brokeredMsg);