Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Messages queues don't need to be scary.

Messages queues don't need to be scary.

An introduction tutorial to AMQP with RabbitMQ and Ruby.

Glen Mailer

October 14, 2013
Tweet

More Decks by Glen Mailer

Other Decks in Technology

Transcript

  1. Message queues don't
    need to be scary
    An intro workshop to AMQP

    View Slide

  2. AMQP

    View Slide

  3. Advanced Message

    Queuing Protocol

    View Slide

  4. View Slide

  5. Why?

    View Slide

  6. Job Queue

    Event Stream

    Buffered RPC

    View Slide

  7. Job Queue

    View Slide

  8. Producer Consumer

    View Slide

  9. Producer
    Consumer
    Producer

    View Slide

  10. Producer Consumer
    Producer Consumer

    View Slide

  11. Producer Consumer
    Producer Consumer

    View Slide

  12. Slow Operations

    Expensive Operations

    Brittle Operations

    View Slide

  13. Producer
    c = create_channel
    q = c.queue("task")
    x = c.default_exchange
    x.publish(
    "task",
    "payload"
    )
    Consumer
    c = create_channel
    q = c.queue("task")
    q.subscribe(worker)
    worker = fn(*message)
    {
    // do stuff
    }

    View Slide

  14. Acknowledging Messages
    q = c.queue("task")
    q.subscribe(worker, ack = TRUE)
    worker = fn(info, metadata, body) {
    // do work
    c.acknowledge(info.delivery_tag)
    }

    View Slide

  15. Publishing Options
    Mandatory
    Will error if not queued
    Immediate
    Will error if no consumer available
    Confirm
    Server acknowledges receipt

    View Slide

  16. Queue Declare Options
    Passive
    Don't create, get reference to
    existing queue
    Durable
    Queue still exists after a broker
    restart

    View Slide

  17. Event Stream

    View Slide

  18. Producer
    Consumer
    Producer
    Consumer
    Consumer
    Consumer
    Producer

    View Slide

  19. Topic Exchange
    routing.key
    Exact match
    routing.*.key
    routing.#.key
    Wildcard
    matching
    routing.key
    routing.a.key
    routing.b.key
    routing.a.b.key

    View Slide

  20. (soft) Real-time updates

    User notifications

    Work distribution

    View Slide

  21. Binding a Queue
    x = c.exchange("activity”)
    q = c.queue("alert")
    q.bind(x, "balance.*")
    q.bind(x, "transfer.out")
    x.publish("balance.low")
    x.publish("transfer.in")
    x.publish("transfer.out")

    View Slide

  22. Queue Declare Options
    Exclusive
    Only one consumer on this queue
    at any time
    Auto Delete
    Queue is deleted after consumer
    disconnects

    View Slide

  23. Simulator Demo

    View Slide

  24. Buffered RPC

    View Slide

  25. Producer
    Consumer

    View Slide

  26. Message Header

    Reply To

    Correlation ID

    View Slide

  27. Reply To
    reply = c.queue("abcdef")
    x.publish("request", :headers => {
    :replyTo => "abcdef"
    })
    reply.subscribe(handleResponse)

    View Slide

  28. Correlation ID
    x.publish("request1", :headers => {
    :replyTo => "abcdef",
    :correlationID => "request1"
    })
    x.publish("request2", :headers => {
    :replyTo => "abcdef",
    :correlationID => "request2"
    })

    View Slide

  29. Smooth out Spikes

    Transparently scale

    Deferred Response

    View Slide

  30. Why not just
    use … ?

    View Slide

  31. Delayed Job

    Resque / Sidekiq

    Beanstalkd

    View Slide

  32. JMS

    Stomp

    MQTT

    View Slide

  33. ØMQ

    View Slide

  34. Ruby Quickstart

    View Slide

  35. gem install bunny

    View Slide

  36. require 'bunny'


    url = 'amqp://un:pw@host:5672/vhost'

    conn = Bunny.new(url)

    conn.start

    ch = conn.create_channel

    ch.prefetch 1

    View Slide

  37. declare_options = {:no_declare => true}

    q = ch.queue(name, options)


    options = {:block => true, :ack => true}

    q.subscribe(options) do |info, meta, body|

    # do stuff

    ch.ack(info.delivery_tag)

    end

    View Slide

  38. declare_options = {:no_declare => true}

    x = ch.topic("name", declare_options)


    x.publish("message", :routing_key => "key")

    View Slide