RabbitMQ has great durability support, but it's usually not enabled by default in the drivers. To persist messages to disk, and thus survive a server restart, you need to publish to a durable exchange, the receiving queue has to be durable, and you got to set the "persistent" flag on the message you're publishing.

require "amqp"

EM.run do
  AMQP.connection = AMQP.connect ENV['CLOUDAMQP_URL'] || 'amqp://guest:guest@localhost'

  AMQP::Channel.new do |ch|
    # Define a durable exchange
    topic = ch.topic('mytopic', durable: true)

    # Define a durable queue, with replication (the x-ha-policy=all argument)
    q1 = ch.queue('my-queue', durable: true, arguments: { 'x-ha-policy' => 'all' })

    # bind the queue to the exchange, limiting to a routing key
    q1.bind(topic, routing_key: 'my.route')

    # Publish a message and set the "persistent" flag
    msg = { :a => 1 }.to_json
    topic.publish(msg, routing_key: 'my.route', persistent: true)

In Python (with Pika) it's a little different, there you set the delivery_mode to 2.

             delivery_mode = 2, # make message persistent

Replication High availablity queues

All queues are by default replicated between all nodes in the cluster you're connected to so no extra queue arguments are needed anymore.

More information on HA is available from RabbitMQ.com.