应用程序实例之间的不兼容:防止 rabbitmq 使用特定 header 消费消息

Incompatibility between app instances: prevent rabbitmq to consume messages with particular header

我有两个使用 spring 和 rabbitmq 的相同 java 应用程序实例。 一个实例向 [=​​46=] 发送一条消息,但我无法预测哪个实例将使用它(如预期的那样)。

我更新了 java 应用程序。由于某些原因,新旧版本之间不兼容:新版本不能使用旧版本的消息,反之亦然。

我们无法在部署新版本时中断服务,因此我们无法同时停止两个实例。我们必须停止实例 A,用更新重启实例 A,然后停止 B 并用更新重启它。

当我拥有 A 的新实例和 B 的旧实例时,如果消息是由 B 生成的,则 A 无法按预期消费消息。

为了解决这个问题,我的想法是在 rabbitmq 消息中添加一个 header。我创建了一个自定义 rabbitmq 模板:

@Override
protected Message convertMessageIfNecessary(final Object object) {
    Message message = super.convertMessageIfNecessary(object);
    MessageProperties messageProperties = new MessageProperties();
    messageProperties.setHeader("version", version);        
    return new Message(message.getBody(), messageProperties);
}

这会添加一个新的 header 以及应用程序的版本。然后我想在确认消息之前检查这个header。

例如:

这样的配置可以吗?

我也查看了 @RabbitListener 组属性,但我不确定该怎么做。

感谢您的帮助

你可以这样做,但效率不高。当 B(3) 实例拒绝该消息时,不能保证重新传递将转到 B(4) 实例;虽然这可能最终会发生,但视情况而定,它可能会先进入 B(3) 很多次。

可能easier/better简单的绑定一个新队列到exchange;让 A(4) 发布到新队列,B(4) 从新队列消费,而旧 B(3) 从旧队列消费。

当所有 A(3) 实例都已取消部署并且所有消息都从旧队列中消耗后,删除最后一个 B(3) 并删除队列。