Theres a rabbit on my symfony

Post on 11-May-2015

18,401 views 3 download

Tags:

description

Talk given at Symfony Live Paris 2011 http://www.symfony-live.com/paris/schedule#session-av1

transcript

There's a Rabbit on my Symfony

Álvaro Videla

Symfony Live 2011

RabbitMQ and Symfony2 Integration

Thursday, March 3, 2011

Who?

Thursday, March 3, 2011

About Me

• Development Manager at TheNetCircle.com

• Blog: http://videlalvaro.github.com/

• Twitter: @old_sound

Thursday, March 3, 2011

About Me

• Developer at Liip

• Blog: http://videlalvaro.github.com/

• Twitter: @old_sound

Thursday, March 3, 2011

About Me

Co-authoring

RabbitMQ in Action

http://bit.ly/rabbitmq

Thursday, March 3, 2011

Why Do I need RabbitMQ?

Thursday, March 3, 2011

Or

Thursday, March 3, 2011

Why Do I need Messaging?

Thursday, March 3, 2011

An Upload PictureForm as seen by:

Thursday, March 3, 2011

The User

Thursday, March 3, 2011

I don’t want to waittill your app resizes

my image!

Thursday, March 3, 2011

The Product Owner

Thursday, March 3, 2011

Can we also notify the user friends when she uploads a new image?

Thursday, March 3, 2011

Can we also notify the user friends when she uploads a new image?

I forgot to mention we need it for tomorrow…

Thursday, March 3, 2011

The Sysadmin

Thursday, March 3, 2011

Dumb! You’re delivering full size images!

The bandwidth bill has tripled!

Thursday, March 3, 2011

Dumb! You’re delivering full size images!

The bandwidth bill has tripled!

We need this fixed for yesterday!

Thursday, March 3, 2011

The Developer in the other team

Thursday, March 3, 2011

I need to call your PHP stuff but from Python

Thursday, March 3, 2011

I need to call your PHP stuff but from Python

And also Java starting next week

Thursday, March 3, 2011

You

Thursday, March 3, 2011

FML!

Thursday, March 3, 2011

Is there a solution?

Thursday, March 3, 2011

RabbitMQ & AMQP

Thursday, March 3, 2011

AMQP

Thursday, March 3, 2011

AMQP

• Advanced Message Queuing Protocol

• Suits Interoperability

• Completely Open Protocol

• Binary Protocol

• AMQP Model

• AMQP Wire Format

Thursday, March 3, 2011

AMQP Model

• Exchanges

• Message Queues

• Bindings

• Rules for binding them

Thursday, March 3, 2011

AMQP Wire Protocol

• Functional Layer

• Transport Layer

Thursday, March 3, 2011

Message Flow

http://www.redhat.com/docs/en-US/Red_Hat_Enterprise_MRG/1.0/html/Messaging_Tutorial/chap-Messaging_Tutorial-Initial_Concepts.html

Thursday, March 3, 2011

Exchange Types

• Fanout

• Direct

• Topic

Thursday, March 3, 2011

Usage Scenarios

Thursday, March 3, 2011

Usage Scenarios

• Batch Processing

Thursday, March 3, 2011

Usage Scenarios

• Batch Processing

• Image Uploading

Thursday, March 3, 2011

Usage Scenarios

• Batch Processing

• Image Uploading

• Distributed Logging

Thursday, March 3, 2011

Scenario

Batch Processing

Thursday, March 3, 2011

Requirements

Thursday, March 3, 2011

Requirements

• Generate XML

Thursday, March 3, 2011

Requirements

• Generate XML

• Distribution Over a Cluster

Thursday, March 3, 2011

Requirements

• Generate XML

• Distribution Over a Cluster

• Elasticity - Add/Remove new workers

Thursday, March 3, 2011

Requirements

• Generate XML

• Distribution Over a Cluster

• Elasticity - Add/Remove new workers

• No Code Changes

Thursday, March 3, 2011

Design

Thursday, March 3, 2011

Publisher Code

$conn = new AMQPConnection(HOST, PORT, USER, PASS, VHOST);$channel = $conn->channel();

$channel->exchange_declare('video-desc-ex', 'direct', false, true, false);

$msg = new AMQPMessage($video_info, array('content_type' => 'text/plain',

'delivery_mode' => 2));

$channel->basic_publish($msg, 'video-desc-ex');

$channel->close();$conn->close();

Thursday, March 3, 2011

Publisher Code

$conn = new AMQPConnection(HOST, PORT, USER, PASS, VHOST);$channel = $conn->channel();

$channel->exchange_declare('video-desc-ex', 'direct', false, true, false);

$msg = new AMQPMessage($video_info, array('content_type' => 'text/plain',

'delivery_mode' => 2));

$channel->basic_publish($msg, 'video-desc-ex');

$channel->close();$conn->close();

Thursday, March 3, 2011

Publisher Code

$conn = new AMQPConnection(HOST, PORT, USER, PASS, VHOST);$channel = $conn->channel();

$channel->exchange_declare('video-desc-ex', 'direct', false, true, false);

$msg = new AMQPMessage($video_info, array('content_type' => 'text/plain',

'delivery_mode' => 2));

$channel->basic_publish($msg, 'video-desc-ex');

$channel->close();$conn->close();

Thursday, March 3, 2011

Publisher Code

$conn = new AMQPConnection(HOST, PORT, USER, PASS, VHOST);$channel = $conn->channel();

$channel->exchange_declare('video-desc-ex', 'direct', false, true, false);

$msg = new AMQPMessage($video_info, array('content_type' => 'text/plain',

'delivery_mode' => 2));

$channel->basic_publish($msg, 'video-desc-ex');

$channel->close();$conn->close();

Thursday, March 3, 2011

Publisher Code

$conn = new AMQPConnection(HOST, PORT, USER, PASS, VHOST);$channel = $conn->channel();

$channel->exchange_declare('video-desc-ex', 'direct', false, true, false);

$msg = new AMQPMessage($video_info, array('content_type' => 'text/plain',

'delivery_mode' => 2));

$channel->basic_publish($msg, 'video-desc-ex');

$channel->close();$conn->close();

Thursday, March 3, 2011

Publisher Code

$conn = new AMQPConnection(HOST, PORT, USER, PASS, VHOST);$channel = $conn->channel();

$channel->exchange_declare('video-desc-ex', 'direct', false, true, false);

$msg = new AMQPMessage($video_info, array('content_type' => 'text/plain',

'delivery_mode' => 2));

$channel->basic_publish($msg, 'video-desc-ex');

$channel->close();$conn->close();

Thursday, March 3, 2011

Consumer Code

$conn = new AMQPConnection(HOST, PORT, USER, PASS, VHOST);$channel = $conn->channel();

$channel->exchange_declare('video-desc-ex', 'direct', false, true, false);

$channel->queue_declare('video-desc-queue', false, true, false, false);

$channel->queue_bind('video-desc-queue', 'video-desc-ex');

$channel->basic_consume('video-desc-queue', $consumer_tag, false, false, false, false, $consumer);

while(count($channel->callbacks)) { $channel->wait();}

Thursday, March 3, 2011

Consumer Code

$conn = new AMQPConnection(HOST, PORT, USER, PASS, VHOST);$channel = $conn->channel();

$channel->exchange_declare('video-desc-ex', 'direct', false, true, false);

$channel->queue_declare('video-desc-queue', false, true, false, false);

$channel->queue_bind('video-desc-queue', 'video-desc-ex');

$channel->basic_consume('video-desc-queue', $consumer_tag, false, false, false, false, $consumer);

while(count($channel->callbacks)) { $channel->wait();}

Thursday, March 3, 2011

Consumer Code

$conn = new AMQPConnection(HOST, PORT, USER, PASS, VHOST);$channel = $conn->channel();

$channel->exchange_declare('video-desc-ex', 'direct', false, true, false);

$channel->queue_declare('video-desc-queue', false, true, false, false);

$channel->queue_bind('video-desc-queue', 'video-desc-ex');

$channel->basic_consume('video-desc-queue', $consumer_tag, false, false, false, false, $consumer);

while(count($channel->callbacks)) { $channel->wait();}

Thursday, March 3, 2011

Consumer Code

$conn = new AMQPConnection(HOST, PORT, USER, PASS, VHOST);$channel = $conn->channel();

$channel->exchange_declare('video-desc-ex', 'direct', false, true, false);

$channel->queue_declare('video-desc-queue', false, true, false, false);

$channel->queue_bind('video-desc-queue', 'video-desc-ex');

$channel->basic_consume('video-desc-queue', $consumer_tag, false, false, false, false, $consumer);

while(count($channel->callbacks)) { $channel->wait();}

Thursday, March 3, 2011

Consumer Code

$conn = new AMQPConnection(HOST, PORT, USER, PASS, VHOST);$channel = $conn->channel();

$channel->exchange_declare('video-desc-ex', 'direct', false, true, false);

$channel->queue_declare('video-desc-queue', false, true, false, false);

$channel->queue_bind('video-desc-queue', 'video-desc-ex');

$channel->basic_consume('video-desc-queue', $consumer_tag, false, false, false, false, $consumer);

while(count($channel->callbacks)) { $channel->wait();}

Thursday, March 3, 2011

Consumer Code

$conn = new AMQPConnection(HOST, PORT, USER, PASS, VHOST);$channel = $conn->channel();

$channel->exchange_declare('video-desc-ex', 'direct', false, true, false);

$channel->queue_declare('video-desc-queue', false, true, false, false);

$channel->queue_bind('video-desc-queue', 'video-desc-ex');

$channel->basic_consume('video-desc-queue', $consumer_tag, false, false, false, false, $consumer);

while(count($channel->callbacks)) { $channel->wait();}

Thursday, March 3, 2011

Consumer Code

$conn = new AMQPConnection(HOST, PORT, USER, PASS, VHOST);$channel = $conn->channel();

$channel->exchange_declare('video-desc-ex', 'direct', false, true, false);

$channel->queue_declare('video-desc-queue', false, true, false, false);

$channel->queue_bind('video-desc-queue', 'video-desc-ex');

$channel->basic_consume('video-desc-queue', $consumer_tag, false, false, false, false, $consumer);

while(count($channel->callbacks)) { $channel->wait();}

Thursday, March 3, 2011

Scenario

Upload Pictures

Thursday, March 3, 2011

Requirements

Thursday, March 3, 2011

Requirements

• Upload Picture

Thursday, March 3, 2011

Requirements

• Upload Picture

• Reward User

Thursday, March 3, 2011

Requirements

• Upload Picture

• Reward User

• Notify User Friends

Thursday, March 3, 2011

Requirements

• Upload Picture

• Reward User

• Notify User Friends

• Resize Picture

Thursday, March 3, 2011

Requirements

• Upload Picture

• Reward User

• Notify User Friends

• Resize Picture

• No Code Changes

Thursday, March 3, 2011

Design

Thursday, March 3, 2011

Design

Thursday, March 3, 2011

Design

Thursday, March 3, 2011

Publisher Code$channel->exchange_declare('upload-pictures', 'fanout', false, true, false);

$metadata = json_encode(array('image_id' => $image_id,'user_id' => $user_id,‘image_path' => $image_path));

$msg = new AMQPMessage($metadata, array('content_type' => 'application/json', 'delivery_mode' => 2));

$channel->basic_publish($msg, 'upload-pictures');

Thursday, March 3, 2011

Publisher Code$channel->exchange_declare('upload-pictures', 'fanout', false, true, false);

$metadata = json_encode(array('image_id' => $image_id,'user_id' => $user_id,‘image_path' => $image_path));

$msg = new AMQPMessage($metadata, array('content_type' => 'application/json', 'delivery_mode' => 2));

$channel->basic_publish($msg, 'upload-pictures');

Thursday, March 3, 2011

Publisher Code$channel->exchange_declare('upload-pictures', 'fanout', false, true, false);

$metadata = json_encode(array('image_id' => $image_id,'user_id' => $user_id,‘image_path' => $image_path));

$msg = new AMQPMessage($metadata, array('content_type' => 'application/json', 'delivery_mode' => 2));

$channel->basic_publish($msg, 'upload-pictures');

Thursday, March 3, 2011

Publisher Code$channel->exchange_declare('upload-pictures', 'fanout', false, true, false);

$metadata = json_encode(array('image_id' => $image_id,'user_id' => $user_id,‘image_path' => $image_path));

$msg = new AMQPMessage($metadata, array('content_type' => 'application/json', 'delivery_mode' => 2));

$channel->basic_publish($msg, 'upload-pictures');

Thursday, March 3, 2011

Publisher Code$channel->exchange_declare('upload-pictures', 'fanout', false, true, false);

$metadata = json_encode(array('image_id' => $image_id,'user_id' => $user_id,‘image_path' => $image_path));

$msg = new AMQPMessage($metadata, array('content_type' => 'application/json', 'delivery_mode' => 2));

$channel->basic_publish($msg, 'upload-pictures');

Thursday, March 3, 2011

Consumer Code$channel->exchange_declare('upload-pictures', 'fanout',

false, true, false);

$channel->queue_declare('resize-picture', false, true, false, false);

$channel->queue_bind('resize-picture', 'upload-pictures');

$channel->basic_consume('resize-picture', $consumer_tag, false, false, false, false, $consumer);

while(count($channel->callbacks)) {$channel->wait();

}

Thursday, March 3, 2011

Consumer Code$channel->exchange_declare('upload-pictures', 'fanout',

false, true, false);

$channel->queue_declare('resize-picture', false, true, false, false);

$channel->queue_bind('resize-picture', 'upload-pictures');

$channel->basic_consume('resize-picture', $consumer_tag, false, false, false, false, $consumer);

while(count($channel->callbacks)) {$channel->wait();

}

Thursday, March 3, 2011

Consumer Code$channel->exchange_declare('upload-pictures', 'fanout',

false, true, false);

$channel->queue_declare('resize-picture', false, true, false, false);

$channel->queue_bind('resize-picture', 'upload-pictures');

$channel->basic_consume('resize-picture', $consumer_tag, false, false, false, false, $consumer);

while(count($channel->callbacks)) {$channel->wait();

}

Thursday, March 3, 2011

Consumer Code$channel->exchange_declare('upload-pictures', 'fanout',

false, true, false);

$channel->queue_declare('resize-picture', false, true, false, false);

$channel->queue_bind('resize-picture', 'upload-pictures');

$channel->basic_consume('resize-picture', $consumer_tag, false, false, false, false, $consumer);

while(count($channel->callbacks)) {$channel->wait();

}

Thursday, March 3, 2011

Consumer Code$channel->exchange_declare('upload-pictures', 'fanout',

false, true, false);

$channel->queue_declare('resize-picture', false, true, false, false);

$channel->queue_bind('resize-picture', 'upload-pictures');

$channel->basic_consume('resize-picture', $consumer_tag, false, false, false, false, $consumer);

while(count($channel->callbacks)) {$channel->wait();

}

Thursday, March 3, 2011

Consumer Code$channel->exchange_declare('upload-pictures', 'fanout',

false, true, false);

$channel->queue_declare('resize-picture', false, true, false, false);

$channel->queue_bind('resize-picture', 'upload-pictures');

$channel->basic_consume('resize-picture', $consumer_tag, false, false, false, false, $consumer);

while(count($channel->callbacks)) {$channel->wait();

}

Thursday, March 3, 2011

Consumer Code

$consumer = function($msg){

$meta = json_decode($msg->body, true);

resize_picture($meta['image_id'], $meta['image_path']);

$msg->delivery_info['channel']->basic_ack($msg->delivery_info['delivery_tag']);

};

Thursday, March 3, 2011

Consumer Code

$consumer = function($msg){

$meta = json_decode($msg->body, true);

resize_picture($meta['image_id'], $meta['image_path']);

$msg->delivery_info['channel']->basic_ack($msg->delivery_info['delivery_tag']);

};

Thursday, March 3, 2011

Consumer Code

$consumer = function($msg){

$meta = json_decode($msg->body, true);

resize_picture($meta['image_id'], $meta['image_path']);

$msg->delivery_info['channel']->basic_ack($msg->delivery_info['delivery_tag']);

};

Thursday, March 3, 2011

Consumer Code

$consumer = function($msg){

$meta = json_decode($msg->body, true);

resize_picture($meta['image_id'], $meta['image_path']);

$msg->delivery_info['channel']->basic_ack($msg->delivery_info['delivery_tag']);

};

Thursday, March 3, 2011

Consumer Code

$consumer = function($msg){

$meta = json_decode($msg->body, true);

resize_picture($meta['image_id'], $meta['image_path']);

$msg->delivery_info['channel']->basic_ack($msg->delivery_info['delivery_tag']);

};

Thursday, March 3, 2011

Scenario

Distributed Logging

Thursday, March 3, 2011

Requirements

Thursday, March 3, 2011

Requirements

• Several Web Servers

Thursday, March 3, 2011

Requirements

• Several Web Servers

• Logic Separated by Module/Action

Thursday, March 3, 2011

Requirements

• Several Web Servers

• Logic Separated by Module/Action

• Several Log Levels:

Thursday, March 3, 2011

Requirements

• Several Web Servers

• Logic Separated by Module/Action

• Several Log Levels:

• Info, Warning, Error

Thursday, March 3, 2011

Requirements

• Several Web Servers

• Logic Separated by Module/Action

• Several Log Levels:

• Info, Warning, Error

• Add/Remove log listeners at will

Thursday, March 3, 2011

Design

Thursday, March 3, 2011

Design

Thursday, March 3, 2011

Design

Thursday, March 3, 2011

Design

Thursday, March 3, 2011

Design

Thursday, March 3, 2011

Publisher Code

$channel->exchange_declare('logs', 'topic', false, true, false);

$msg = new AMQPMessage('some log message',array('content_type' => 'text/plain'));

$channel->basic_publish($msg, 'logs', server1.user.profile.info');

Thursday, March 3, 2011

Publisher Code

$channel->exchange_declare('logs', 'topic', false, true, false);

$msg = new AMQPMessage('some log message',array('content_type' => 'text/plain'));

$channel->basic_publish($msg, 'logs', server1.user.profile.info');

Thursday, March 3, 2011

Publisher Code

$channel->exchange_declare('logs', 'topic', false, true, false);

$msg = new AMQPMessage('some log message',array('content_type' => 'text/plain'));

$channel->basic_publish($msg, 'logs', server1.user.profile.info');

Thursday, March 3, 2011

Publisher Code

$channel->exchange_declare('logs', 'topic', false, true, false);

$msg = new AMQPMessage('some log message',array('content_type' => 'text/plain'));

$channel->basic_publish($msg, 'logs', server1.user.profile.info');

Thursday, March 3, 2011

Consumer Code

Get messages sent by host:

server1

Thursday, March 3, 2011

Consumer Code

$channel->exchange_declare('logs', 'topic', false, true, false);

$channel->queue_declare('server1-logs', false, true, false, false);

$channel->queue_bind('server1-logs', 'logs', 'server1.#');

Thursday, March 3, 2011

Consumer Code

$channel->exchange_declare('logs', 'topic', false, true, false);

$channel->queue_declare('server1-logs', false, true, false, false);

$channel->queue_bind('server1-logs', 'logs', 'server1.#');

Thursday, March 3, 2011

Consumer Code

$channel->exchange_declare('logs', 'topic', false, true, false);

$channel->queue_declare('server1-logs', false, true, false, false);

$channel->queue_bind('server1-logs', 'logs', 'server1.#');

Thursday, March 3, 2011

Consumer Code

$channel->exchange_declare('logs', 'topic', false, true, false);

$channel->queue_declare('server1-logs', false, true, false, false);

$channel->queue_bind('server1-logs', 'logs', 'server1.#');

Thursday, March 3, 2011

Consumer Code

Get all error messages

Thursday, March 3, 2011

Consumer Code

$channel->exchange_declare('logs', 'topic', false, true, false);

$channel->queue_declare('error-logs', false, true, false, false);

$channel->queue_bind('error-logs', 'logs', '#.error');

Thursday, March 3, 2011

Consumer Code

$channel->exchange_declare('logs', 'topic', false, true, false);

$channel->queue_declare('error-logs', false, true, false, false);

$channel->queue_bind('error-logs', 'logs', '#.error');

Thursday, March 3, 2011

Consumer Code

$channel->exchange_declare('logs', 'topic', false, true, false);

$channel->queue_declare('error-logs', false, true, false, false);

$channel->queue_bind('error-logs', 'logs', '#.error');

Thursday, March 3, 2011

Consumer Code

$channel->exchange_declare('logs', 'topic', false, true, false);

$channel->queue_declare('error-logs', false, true, false, false);

$channel->queue_bind('error-logs', 'logs', '#.error');

Thursday, March 3, 2011

Symfony Integration

Thursday, March 3, 2011

RabbitMQ Bundle

Thursday, March 3, 2011

RabbitMQ Bundle

To be easy to use

Goal:

Thursday, March 3, 2011

RabbitMQ Bundle

$msg = array('user_id' => 1235, 'image_path' => '/path/to/new/pic.png');

$this->get('rabbitmq.upload_picture_producer')-> publish(serialize($msg));

Publish a Message:

Thursday, March 3, 2011

RabbitMQ Bundle

$ ./app/console_dev rabbitmq:consumer -m 1 upload_picture

Consume a Message:

Thursday, March 3, 2011

RabbitMQ Bundle

$ ./app/console_dev rabbitmq:consumer -m 50 upload_picture

Consume 50 Messages:

Thursday, March 3, 2011

RabbitMQ Bundle

$ ./app/console_dev rabbitmq:consumer -m -1 upload_picture

Consume infinite* Messages:

*messages may not be infinite

Thursday, March 3, 2011

RabbitMQ Bundle

# app/config/config.ymlrabbitmq.config: connections: default: host: 'localhost' port: 5672 user: 'guest' password: 'guest' vhost: '/'

Configuration:

Thursday, March 3, 2011

RabbitMQ Bundle

# app/config/config.ymlrabbitmq.config: connections:

...producers:

upload_picture: connection: default exchange_options: {name: 'upload-picture',

type: direct}

Configuration:

Thursday, March 3, 2011

RabbitMQ Bundle

# app/config/config.ymlrabbitmq.config: connections:

... consumers:

upload_picture: connection: default exchange_options: {name: 'upload-picture',

type: direct} queue_options: {name: 'upload-picture'} callback: upload_picture_service

Configuration:

Thursday, March 3, 2011

RabbitMQ Bundle

public function indexAction($name){ ... $msg = array('user_id' => 1235,

'image_path' => '/path/to/new/pic.png');

$this->get('rabbitmq.upload_picture_producer')->publish(serialize($msg));

...}

Using a Producer:

Thursday, March 3, 2011

RabbitMQ Bundle

class UploadPictureConsumer extends ContainerAware implements ConsumerInterface{ public function execute($msg) { // Process picture upload. // $msg will be what was published

// from the Controller. }}

Consumer Class:

Thursday, March 3, 2011

RabbitMQ Bundle

Recap:

Thursday, March 3, 2011

RabbitMQ Bundle

• Add an entry for the consumer/producer in the configuration.

Recap:

Thursday, March 3, 2011

RabbitMQ Bundle

• Add an entry for the consumer/producer in the configuration.

• Implement your Callback.

Recap:

Thursday, March 3, 2011

RabbitMQ Bundle

• Add an entry for the consumer/producer in the configuration.

• Implement your Callback.

• Start the consumer from the CLI.

Recap:

Thursday, March 3, 2011

RabbitMQ Bundle

• Add an entry for the consumer/producer in the configuration.

• Implement your Callback.

• Start the consumer from the CLI.

• Add code to publish messages.

Recap:

Thursday, March 3, 2011

RabbitMQ Bundle

There’s more:

Thursday, March 3, 2011

RabbitMQ Bundle

• RPC clients and servers

There’s more:

Thursday, March 3, 2011

RabbitMQ Bundle

• RPC clients and servers

• Anonymous consumers

There’s more:

Thursday, March 3, 2011

RabbitMQ Bundle

• RPC clients and servers

• Anonymous consumers

• Parallel RPC

There’s more:

Thursday, March 3, 2011

RabbitMQ Bundle

http://github.com/videlalvaro/RabbitMqBundle

Fork it at

Thursday, March 3, 2011

Why RabbitMQ?

Thursday, March 3, 2011

RabbitMQ

• Enterprise Messaging System

• Open Source MPL

• Written in Erlang/OTP

• Commercial Support

Thursday, March 3, 2011

Features

• Reliable and High Scalable

• Easy To install

• Easy To Cluster

• Runs on: Windows, Solaris, Linux, OSX

• AMQP 0.8 - 0.9.1

Thursday, March 3, 2011

Client Libraries

• Java

• .NET/C#

• Erlang

• Ruby, Python, PHP, Perl, AS3, Lisp, Scala, Clojure, Haskell

Thursday, March 3, 2011

Docs/Support

• http://www.rabbitmq.com/documentation.html

• http://dev.rabbitmq.com/wiki/

• #rabbitmq at irc.freenode.net

• http://www.rabbitmq.com/email-archive.html

Thursday, March 3, 2011

One Setup for HA

Thursday, March 3, 2011

Conclusion

Thursday, March 3, 2011

Conclusion

• Flexibility

Thursday, March 3, 2011

Conclusion

• Flexibility

• Scalability

Thursday, March 3, 2011

Conclusion

• Flexibility

• Scalability

• Interoperability

Thursday, March 3, 2011

Conclusion

• Flexibility

• Scalability

• Interoperability

• Reduce Ops

Thursday, March 3, 2011

Questions?

Thursday, March 3, 2011

Thanks!Álvaro Videla

http://twitter.com/old_sound

http://github.com/videlalvaro

http://github.com/tnc

http://www.slideshare.net/old_sound

Thursday, March 3, 2011