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

时间:2014-11-27 10:02:47

标签: c# version azureservicebus servicebus

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

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

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

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

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

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

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

  3. 是否可以通过修改投放时间推迟邮件?几分钟就没事了。如果到那时仍然运行相同的服务,则可以再次推迟。 (工作代码示例将不胜感激!)

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

3 个答案:

答案 0 :(得分:1)

根据经验,现场系统升级很困难。最小化系统停机风险的最简单方法是:

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

答案 1 :(得分:1)

我一直在寻找类似的东西,但我还没有实现它,所以无法提供完整的指导,但回答#3上的问题......我的消息有一个标志来重新排队消息运行再次,例如让流程每5分钟运行一次。

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

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

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

 BrokeredMessage brokeredMsg = new BrokeredMessage(myObject);
 brokeredMsg.ScheduledEnqueueTimeUtc = DateTime.UtcNow.AddMinutes(5);
 Client.Send(brokeredMsg);

因此,如果您只想一次处理一个模型版本,则可以为模型分配版本号,并将某些内容编入处理器以查找特定型号。如果模型较高,则将其重新排队一段时间(直到您更新了代码)。如果它更低(错过的消息),那么可能会有一些异常处理。

答案 2 :(得分:1)

在邮件中使用自定义MessageProperty,例如Version

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

然后您可以升级发件人 - 新邮件将仅存储在新的&#39;临时&#39;订阅。

之后,您升级侦听器,更改订阅规则(从主要&#39;订阅中删除版本规则,禁用临时订阅接收)。

现在你可以选择:

  • 使用任何工具读取临时订阅的消息并将其写回主题 - 它们将到达升级后的听众。
  • 暂时启动一个将读取临时订阅并处理其中所有消息的侦听器
  • 特定于您的架构的其他方式