An introduction tutorial to AMQP with RabbitMQ and Ruby.
Message queues don'tneed to be scaryAn intro workshop to AMQP
View Slide
AMQP
Advanced Message Queuing Protocol
Why?
Job Queue Event Stream Buffered RPC
Job Queue
Producer Consumer
ProducerConsumerProducer
Producer ConsumerProducer Consumer
Slow Operations Expensive Operations Brittle Operations
Producerc = create_channelq = c.queue("task")x = c.default_exchangex.publish("task","payload")Consumerc = create_channelq = c.queue("task")q.subscribe(worker)worker = fn(*message){// do stuff}
Acknowledging Messagesq = c.queue("task")q.subscribe(worker, ack = TRUE)worker = fn(info, metadata, body) {// do workc.acknowledge(info.delivery_tag)}
Publishing OptionsMandatoryWill error if not queuedImmediateWill error if no consumer availableConfirmServer acknowledges receipt
Queue Declare OptionsPassiveDon't create, get reference toexisting queueDurableQueue still exists after a brokerrestart
Event Stream
ProducerConsumerProducerConsumerConsumerConsumerProducer
Topic Exchangerouting.keyExact matchrouting.*.keyrouting.#.keyWildcardmatchingrouting.keyrouting.a.keyrouting.b.keyrouting.a.b.key
(soft) Real-time updates User notifications Work distribution
Binding a Queuex = 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")
Queue Declare OptionsExclusiveOnly one consumer on this queueat any timeAuto DeleteQueue is deleted after consumerdisconnects
Simulator Demo
Buffered RPC
ProducerConsumer
Message Header Reply To Correlation ID
Reply Toreply = c.queue("abcdef")x.publish("request", :headers => {:replyTo => "abcdef"})reply.subscribe(handleResponse)
Correlation IDx.publish("request1", :headers => {:replyTo => "abcdef",:correlationID => "request1"})x.publish("request2", :headers => {:replyTo => "abcdef",:correlationID => "request2"})
Smooth out Spikes Transparently scale Deferred Response
Why not justuse … ?
Delayed Job Resque / Sidekiq Beanstalkd
JMS Stomp MQTT
ØMQ
Ruby Quickstart
gem install bunny
require 'bunny' url = 'amqp://un:pw@host:5672/vhost' conn = Bunny.new(url) conn.start ch = conn.create_channel ch.prefetch 1
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
declare_options = {:no_declare => true} x = ch.topic("name", declare_options) x.publish("message", :routing_key => "key")