messaging
RabbitMQ
Rabbit MQ
- AMQP broker
- AMQP defines messaging protocol (http://amqp.org)
- Written in Erlang
- Queues or Message destinations configured via the AMQP protocol
- Messages routed via Exchanges
- Message Routing can be defined using client library (Ruby's amqp gem for example)
- Message Store - File System based (in memory + disk) - http://www.rabbitmq.com/blog/2011/01/20/rabbitmq-backing-stores-databases-and-disks/
Active MQ
- Broker, Messaging Bus
- Supports AMQP protocol via configuration
- AMQP not required though
- Queues/Destination defined via configuration
- Written in Java
- JMS focussed
- Can be used with other clients/languages
- Default Message Store - KahaDB - file based message persistence database
- Also supports most SQL based Databases as message store
MONGO DB
- Capped Collection as a Message Bus
- Message Store backed by Mongo
- Suited for Pub/Sub
- Node.js example (https://gist.github.com/3210919) mimics subscriber/broker behavior using "tailable" cursor
Rabbit MQ routing
rabbit mq routing
AMQP Exchange
- Accepts messages from producer and routes them to message queues
- Messages are always routed and published to Queues via Exchanges using pre-defined criteria called bindings
- Binding - association between Exchange & Queue
- Queue must be bound to at least one exchange to receive messages from publishers.
- Exchange Types - Fanout, Direct, Topic, Headers
- Message attribute routing_key is used by Exchange to route the message to its destination. Analogous to address.
Exchange
exchange = AMQP::Exchange.new(channel, :fanout, "nodes.metadata")
OR
exchange = channel.fanout("nodes.metadata")
Exchange/Queue Binding
- Glue between Exchange and Queue
queue = channel.queue("queue.name", durable: true).bind(exchange)
queue.subscribe { |payload| puts "Queue #{queue.name} received #{payload}" }
Exchange - Fanout
Exchange - Direct
exchange - direct
exchange = AMQP::Exchange.new(channel, :direct, "nodes.metadata")
OR
exchange = channel.direct("nodes.metadata")
exchange - direct
queue = channel.queue("queue.name").bind(exchange, routing_key: "routing.key")
queue.subscribe { |payload| puts "Queue #{queue.name} on channel received #{payload}" }
exchange.publish("Hello, direct exchanges world!", routing_key: "routing.key")
routing key - pattern
channel.queue("us.california").bind(exchange, routing_key: "americas.north.us.ca.*").subscribe
{ |metadata, payload| }
exchange.publish("San Diego update", routing_key: "americas.north.us.ca.sandiego")
exchange.publish("Berkeley update", routing_key: "americas.north.us.ca.berkeley")
AMQP Ruby library - Connection
require "amqp"
EventMachine.run do
# using AMQP.connect with a block
AMQP.connect(host: "localhost") do |connection|
# connection is open and ready to be used
end
end
AMQP RUBY LIBRARY - CONNECTION
require "amqp"
EventMachine.run do
# using AMQP.connect with a block
client = AMQP.connect(host: "localhost", username: "hedgehog", password: "pwd")
# channel object used to create Exchange and Queue
channel = AMQP::Channel.new(connection)
end
AmQp Queue
- FIFO Message Buffers
- Exchange route/store messages to Queue
- Queue has a name to uniquely identify it
- Queue are declared before they can be used
- Declaring a queue will create it, if it does not exists
- AMQP Broker will name a queue, if no name is provided by the client
- Queue needs to bind to an exchange to receive messages
- Queue Types - Durable Shared & Exclusive In-memory
AMQP - Durable queue
queue = AMQP::Queue.new(channel, "images.resize", durable: true)
Durable keys can be accessed by multiple consumers and from different process
AMQP - Exclusive queue
channel.queue("images.resize", auto_delete: true, exclusive: true)
Exclusive queues may only be accessed by the current connection and are deleted when that connection closes
messaging
By kapil
messaging
- 4,885