Wikipedia指出消息队列可以在以下几个特定方面进行配置:
"传递策略——我们需要保证消息至少传递一次,还是不超过一次?"
"排队标准-什么时候消息应该被认为是"已排队"?当一个队列有它的时候?或者当它被转发到至少一个远程队列时?或者对所有的队列?"
"消息过滤——某些系统支持过滤数据,以便订阅者可能只看到符合某些预先指定的感兴趣标准的消息"
"接收通知-发布者可能需要知道部分或所有订阅者何时收到消息。"
请告诉我,在使用Rebus与MSMQ或RabbitMQ时,我可以在哪里配置这些方面?
更新:
我还想再问一个特性:
"批处理策略-应该立即传递消息吗? "或者系统应该稍等一会儿并尝试一次传递多个消息?"
Wikipedia文章描述了消息队列的常见特征,即在给定的消息队列实现中可能/可能不可用的特性。
当你配置Rebus使用MSMQ和RabbitMQ作为传输时,它将默认设置具有以下属性:
交付策略:严格执行至少一次。这是排队系统所能提供的最好保证,因为恰好一次要求排队系统能够与在您正在做的任何工作在同一个事务中工作,而这是不可能的(至少一般来说)。
排队标准:当消息被传递到排队系统没有任何异常时,Rebus认为消息已进入队列。无论是RabbitMQ还是MSMQ, Rebus都将在接收消息时使用的相同队列事务中发送所有传出消息,因此接收/发送操作可以自动提交给队列系统。
Rebus默认使用消息持久性为ON的RabbitMQ,这意味着当RabbitMQ写入磁盘时,消息被认为已经发送。RabbitMQ可能有/可能没有一些额外的持久性选项,我不知道,所以可能会配置你的RabbitMQ服务器来复制消息到其他节点。
对于MSMQ,当消息被写入磁盘时,就认为消息已经传递。由于MSMQ在本地操作,这意味着消息在转发到(可能是远程的)接收消息队列之前总是存储在本地。
消息过滤:在Rebus中,目前没有办法"过滤"消息,除了订阅感兴趣的消息类型。
接收通知: Rebus不支持任何类型的接收——它假设排队系统是可靠和持久的(它是,因为Rebus只以可靠和持久的方式使用它的传输)——因此,所有消息都以即发即弃的方式发送。
如果你想自己实现某种接收机制,你可以自由使用bus.Reply
。
结论:当使用Rebus时,这些东西不能(也很可能不应该)被调整——Rebus以某种方式使用它的传输来提供它的交付保证,如果你绕过它,你可能会意外地破坏它。
我希望这对你有帮助:)
.
关于传递策略的修改-至少一次保证是否意味着接收端必须在:
之前检查给定消息是否已被接收?是的,在某些情况下确实如此——但这取决于你在接收端执行的工作的性质。
在某些情况下,您可能很幸运,该操作本身是幂等的,因此该操作是否执行1次或多次并不重要。
在其他情况下,您可能需要例如存储域信息,如时间戳,或者甚至可能是处理消息的一堆id,以使您的端点以幂等方式工作。
应该注意的是,Rebus总是在队列事务中处理你的消息,如果你在数据库中做你自己的工作,在一个异常的情况下你可以回滚你的工作,那么一切都应该被回滚。
Rebus最终两次传递相同消息的唯一情况是发生以下事件序列:
- 在队列事务中接收消息
- 你在一个数据库事务中工作
- 提交数据库事务
- 队列系统不可达,因此无法提交队列事务
在这种情况下,消息将在一段时间后再次传递。在像MSMQ这样的队列系统上使用Rebus,所有的进程间通信都在本地进程之间进行,因此这种事件序列不太可能发生。
应该注意的是,如果你的数据足够重要,一致性是最重要的,你必须总是以这样或那样的方式使你的端点幂等。