重新启动RabbitMQ后删除Ruby AMQP持久性消息

时间:2011-03-17 15:28:07

标签: ruby rabbitmq amqp

我有一个ruby脚本,可以在RabbitMQ中使用AMQP创建一条消息。

# above code sets up config for connecting to RabbitMQ via APMQ
AMQP.start(:host => 'localhost') do
  amq = MQ.new
  amq.queue('initiate', :durable => true).publish(message_id, :persistent => true)
  AMQP.stop{ EM.stop }
end

如果重新启动RabbitMQ服务器,则该消息不再位于启动队列(或任何队列)中。如果消息不持久,我做错了什么?我还尝试显式创建持久交换,并将队列绑定到该交换,但在RabbitMQ重启后仍然删除该消息。

3 个答案:

答案 0 :(得分:4)

正如已经提到的,如果你只是将消息标记为持久性,它们不一定会立即持久化,所以如果服务器意外关闭,它们可能永远不会在磁盘上结束。

那么,如果你真的需要将消息放在磁盘上,即使服务器崩溃,你会怎么做?

你可以做两件事。一种是将您的发布包装在一个事务中。当您提交了事务时,该消息将在磁盘上(如果它尚未传递给消费者)。但是,这会向服务器添加同步调用,因此可能会降低您的速度。如果你知道你要发布很多消息,你可以在一个事务中包装一堆发布,然后当你提交时你知道它们都在磁盘上。

另一种(更高性能)替代方案是使用发布确认。但这些是2.3.1服务器中的新功能,我认为任何Ruby客户端都不支持它们。

最后,即使没有确认,交易和受控关机,RabbitMQ也会定期将持久性消息刷新到磁盘。但是2.2.0中存在一个错误,这意味着这有时不会发生很长时间,因此升级到2.3.1可能是值得的。

答案 1 :(得分:2)

有趣的是我只是谷歌搜索同样的问题。 RabbitMQ 2.2.0,默认选项。就我而言,Ruby客户端使用EPEL中的rubygem-amqp-0.6.7-3.el5。持久的队列绑定到持久的扇出交换,发布消息:persistent =>真正。服务器重启时丢失的消息。 -Alan

答案 2 :(得分:1)

是的,西蒙是对的。关于出版商确认(在http://www.rabbitmq.com/blog/2011/02/10/introducing-publisher-confirms描述),我计划在AMQP 0.8中支持它们,这将很快发布。

BTW,在原始示例中,发布的第一个参数应该是实际数据,其他所有内容都是通过选项指定的,因此它是发布(消息,opts)而不是发布(message_id,opts)。