重启RabbitMQ后Ruby AMQP持久消息被删除

发布于 2024-10-22 20:24:33 字数 421 浏览 6 评论 0原文

我有一个 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 重新启​​动后消息仍然被删除。

I have a ruby script that creates a message using AMQP in RabbitMQ.

# 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

If the RabbitMQ server is restarted, the message is no longer in the initiate queue (or any queue, for that matter). What am I doing wrong that the message is not persistent? I've also tried explicitly creating a durable exchange, and binding the queue to that exchange, but the message is still deleted after RabbitMQ restart.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

向日葵 2024-10-29 20:24:33

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

那么,如果您确实需要将消息保存在磁盘上,即使服务器崩溃了,您该怎么办?

您可以做两件事。一种是将您的发布包装在事务中。当您提交事务时,消息将存储在磁盘上(当然,如果它尚未传递给消费者)。但是,这会增加对服务器的同步调用,因此会减慢速度。如果您知道要发布大量消息,则可以将一堆发布包装在一个事务中,然后当您提交时,您知道它们都在磁盘上。

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

最后,即使没有确认、事务和受控关闭,RabbitMQ 也会定期将持久消息刷新到磁盘。然而 2.2.0 中存在一个错误,这意味着这种情况有时不会在很长一段时间内发生,因此升级到 2.3.1 可能是值得的。

As already mentioned, if you just mark messages as persistent they will not necessarily get persisted straight away, so if the server shuts down unexpectedly they may never end up on disk.

So what do you do if you really need the message to be on disk, even if the server crashes?

There are two things you can do. One is to wrap your publish in a transaction. When you have committed the transaction, the message will be on disk (if it's not already delivered to a consumer of course). However, this adds a synchronous call to the server, so it can slow you down. If you know you're going to publish a lot of messages, you can wrap a bunch of publishes in a transaction, then when you commit you know they're all on disk.

The other (higher performance) alternative is to use publish confirms. But these are new in the 2.3.1 server and I don't think any Ruby clients support them yet.

Finally, RabbitMQ will anyway periodically flush persistent messages to disk even in the absence of confirms, transactions and controlled shutdowns. However there's a bug in 2.2.0 which means that this sometimes doesn't happen for a long time, so upgrading to 2.3.1 might be worthwhile.

像你 2024-10-29 20:24:33

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

Funny I was just Googling for the same problem. RabbitMQ 2.2.0, default options. In my case, Ruby clients using rubygem-amqp-0.6.7-3.el5 from EPEL. Durable queues bound to Durable fanout exchange, publishing messages with :persistent => true. Messages lost on server restart.
-Alan

猫七 2024-10-29 20:24:33

是的,西蒙是对的。关于发布者确认(参见 http://www.rabbitmq.com /blog/2011/02/10/introducing-publisher-confirms),我计划在即将发布的 AMQP 0.8 中支持它们。

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

Yes, Simon is right. About publisher confirms (described at http://www.rabbitmq.com/blog/2011/02/10/introducing-publisher-confirms), I plan to support them in AMQP 0.8 which shall be released soon.

BTW, in the original example, the first argument for publish is supposed to be the actual data, everything else is specified via options, so it's publish(message, opts) rather than publish(message_id, opts).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文