消息队列设置

时间:2014-08-07 11:34:27

标签: rabbitmq message-queue msmq servicebus rebus

Wikipedia指出消息队列可以在以下特定方面配置:

“投放政策 - 我们是否需要保证邮件至少发送一次,或者不超过一次?”

“排队标准 - 何时应将邮件视为”排队“?当一个队列拥有它时?或者当它被转发到至少一个远程队列?或者所有队列?”

“消息过滤 - 某些系统支持过滤数据,以便订阅者只能看到符合某些预先指定的感兴趣标准的消息”

“收据通知 - 发布商可能需要知道某些或所有订阅者何时收到消息。”

请告诉我,在将Rebus与MSMQ或RabbitMQ一起使用时,我可以在哪里配置这些方面?

更新

我还想再问一个功能:

“批处理策略 - 应该立即发送消息吗?或者系统是否应该稍微等待并尝试一次发送多条消息?”

1 个答案:

答案 0 :(得分:2)

维基百科文章描述了消息队列的常见特征,即在给定的消息队列实现上可能/可能不可用的特征。

当您将Rebus配置为使用MSMQ和RabbitMQ作为传输时,它将默认为具有以下属性的设置:

投放政策:一直严格至少一次。这是排队系统可以提供的最佳保证,因为完全一次会要求排队系统可以在与你正在做的任何工作相同的事务中工作,这是不可能的(至少一般)

排队标准:Rebus会将消息传递到排队系统时将其排队,而不会有任何例外情况。使用RabbitMQ和MSMQ,Rebus将在接收消息时使用的队列事务中发送所有传出消息,因此接收/发送操作可以原子方式提交给排队系统。

Rebus默认使用带有消息durabilit ON的RabbitMQ,这意味着当RabbitMQ写入磁盘时会认为消息已传递。 RabbitMQ可能/可能没有一些我不知道的额外持久性选项,因此可以配置RabbitMQ服务器将消息复制到其他节点。

使用MSMQ,该消息在写入磁盘时被视为已传递。由于MSMQ在本地运行,这意味着在将消息转发到(可能是远程的)接收消息队列之前,消息始终存储在本地。

消息过滤:使用Rebus,除了订阅感兴趣的消息类型之外,目前无法“过滤”消息。

收据通知:Rebus不支持任何类型的收据 - 假设排队系统可靠耐用(因为Rebus仅以可靠和耐用的方式使用其传输) ) - 因此,所有消息都以 fire-and-forget -manner发送。

如果您想自己实施某种收据机制,可以自由使用bus.Reply

结论:当使用Rebus时,这些东西不能(并且很可能不应该)调整 - Rebus以某种方式使用其传输以提供其传递保证,如果你绕过它,你可能会意外地破坏它。

我希望有帮助:)

有关投放政策的修订 - 至少一次保证是否意味着接收方必须在之前检查是否已收到指定邮件:

是的,在某些情况下确实如此 - 但这取决于您在接收端执行的工作的性质。

在某些情况下,您可能很幸运,该操作本身就是idempotent,因此该操作是否执行了1次或更多次无关紧要。

在其他情况下,您可能需要例如存储域信息,如时间戳,或者甚至是一堆已处理消息的ID,以使您的端点以幂等方式工作。

应该注意的是,Rebus总是在队列事务中处理您的消息,如果您在例如自己的工作中处理一个数据库,你可以在异常的情况下回滚你的工作,然后一切都按原样回滚。

Rebus最终会两次发送相同消息的唯一情况是发生以下事件序列:

  1. 您在队列交易中收到消息
  2. 您在数据库事务中完成工作
  3. 您提交数据库事务
  4. 队列系统无法访问,因此无法提交队列事务
  5. 在这种情况下,该消息将在一段时间后再次发送。使用Rebus在像MSMQ这样的排队系统上,所有进程间通信都在本地进程之间进行,这种事件序列不太可能发生。

    应该注意的是,如果您的数据足够重要且一致性至关重要,那么必须始终以某种方式使您的端点具有幂等性。