SlideShare uma empresa Scribd logo
1 de 144
Baixar para ler offline
There's a Rabbit
                          on my Symfony
                            RabbitMQ and Symfony2 Integration




                                   Álvaro Videla



                            Symfony Live 2011

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 Picture
                           Form as seen by:


Thursday, March 3, 2011
The User



Thursday, March 3, 2011
I don’t want to wait
                          till 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
http://www.redhat.com/docs/en-US/Red_Hat_Enterprise_MRG/1.0/html/Messaging_Tutorial/sect-Messaging_Tutorial-Initial_Concepts-
                                                                       Fanout_Exchange.html




Thursday, March 3, 2011
http://www.redhat.com/docs/en-US/Red_Hat_Enterprise_MRG/1.0/html/Messaging_Tutorial/sect-Messaging_Tutorial-Initial_Concepts-
                                                                        Direct_Exchange.html




Thursday, March 3, 2011
http://www.redhat.com/docs/en-US/Red_Hat_Enterprise_MRG/1.0/html/Messaging_Tutorial/sect-Messaging_Tutorial-Initial_Concepts-
                                                                        Topic_Exchange.html




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

                                  Goal:


                            To be easy to use



Thursday, March 3, 2011
RabbitMQ Bundle
                                        Publish a Message:

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

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




Thursday, March 3, 2011
RabbitMQ Bundle
                             Consume a Message:

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




Thursday, March 3, 2011
RabbitMQ Bundle
                            Consume 50 Messages:

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




Thursday, March 3, 2011
RabbitMQ Bundle
                           Consume infinite* Messages:

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




                                    *messages may not be infinite




Thursday, March 3, 2011
RabbitMQ Bundle
                                 Configuration:
           # app/config/config.yml
           rabbitmq.config:
               connections:
                   default:
                       host:       'localhost'
                       port:       5672
                       user:       'guest'
                       password: 'guest'
                       vhost:      '/'




Thursday, March 3, 2011
RabbitMQ Bundle
                                 Configuration:
           # app/config/config.yml
           rabbitmq.config:
               connections:
                   ...
               producers:
                    upload_picture:
                        connection: default
                        exchange_options: {name: 'upload-picture',
                                             type: direct}




Thursday, March 3, 2011
RabbitMQ Bundle
                                Configuration:
           # app/config/config.yml
           rabbitmq.config:
               connections:
                  ...
              consumers:
                   upload_picture:
                       connection: default
                       exchange_options: {name: 'upload-picture',
                                            type: direct}
                       queue_options:    {name: 'upload-picture'}
                       callback:         upload_picture_service




Thursday, March 3, 2011
RabbitMQ Bundle
                                    Using a Producer:
           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));
                     ...
           }




Thursday, March 3, 2011
RabbitMQ Bundle
                               Consumer Class:
           class UploadPictureConsumer extends ContainerAware
           implements ConsumerInterface
           {
               public function execute($msg)
               {
                   // Process picture upload.
                   // $msg will be what was published
                  // from the Controller.
               }
           }




Thursday, March 3, 2011
RabbitMQ Bundle
                                Recap:




Thursday, March 3, 2011
RabbitMQ Bundle
                                              Recap:

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




Thursday, March 3, 2011
RabbitMQ Bundle
                                              Recap:

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


Thursday, March 3, 2011
RabbitMQ Bundle
                                              Recap:

                • Add an entry for the consumer/producer in
                          the configuration.
                • Implement your Callback.
                • Start the consumer from the CLI.

Thursday, March 3, 2011
RabbitMQ Bundle
                                              Recap:

                • Add an entry for the consumer/producer in
                          the configuration.
                • Implement your Callback.
                • Start the consumer from the CLI.
                • Add code to publish messages.
Thursday, March 3, 2011
RabbitMQ Bundle
                              There’s more:




Thursday, March 3, 2011
RabbitMQ Bundle
                                There’s more:

                • RPC clients and servers




Thursday, March 3, 2011
RabbitMQ Bundle
                                There’s more:

                • RPC clients and servers
                • Anonymous consumers



Thursday, March 3, 2011
RabbitMQ Bundle
                                There’s more:

                • RPC clients and servers
                • Anonymous consumers
                • Parallel RPC


Thursday, March 3, 2011
RabbitMQ Bundle
                                           Fork it at


                          http://github.com/videlalvaro/RabbitMqBundle




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

Mais conteúdo relacionado

Mais procurados

Mais procurados (20)

Plugin architecture (Extensible Application Architecture)
Plugin architecture (Extensible Application Architecture)Plugin architecture (Extensible Application Architecture)
Plugin architecture (Extensible Application Architecture)
 
[2018] 프런트엔드 성능 최적화
[2018] 프런트엔드 성능 최적화[2018] 프런트엔드 성능 최적화
[2018] 프런트엔드 성능 최적화
 
Http session (Java)
Http session (Java)Http session (Java)
Http session (Java)
 
Java servlet life cycle - methods ppt
Java servlet life cycle - methods pptJava servlet life cycle - methods ppt
Java servlet life cycle - methods ppt
 
An introduction to maven gradle and sbt
An introduction to maven gradle and sbtAn introduction to maven gradle and sbt
An introduction to maven gradle and sbt
 
Java servlets
Java servletsJava servlets
Java servlets
 
Spring framework in depth
Spring framework in depthSpring framework in depth
Spring framework in depth
 
Spring Framework - Core
Spring Framework - CoreSpring Framework - Core
Spring Framework - Core
 
Spam and Anti Spam Techniques
Spam and Anti Spam TechniquesSpam and Anti Spam Techniques
Spam and Anti Spam Techniques
 
Jsp
JspJsp
Jsp
 
Secure Session Management
Secure Session ManagementSecure Session Management
Secure Session Management
 
Testing with Spring: An Introduction
Testing with Spring: An IntroductionTesting with Spring: An Introduction
Testing with Spring: An Introduction
 
Understanding Cross-site Request Forgery
Understanding Cross-site Request ForgeryUnderstanding Cross-site Request Forgery
Understanding Cross-site Request Forgery
 
Angular Basics.pptx
Angular Basics.pptxAngular Basics.pptx
Angular Basics.pptx
 
Analysis of web application penetration testing
Analysis of web application penetration testingAnalysis of web application penetration testing
Analysis of web application penetration testing
 
Migrating from MFC to Qt
Migrating from MFC to QtMigrating from MFC to Qt
Migrating from MFC to Qt
 
What is dotnet (.NET) ?
What is dotnet (.NET) ?What is dotnet (.NET) ?
What is dotnet (.NET) ?
 
JDBC Java Database Connectivity
JDBC Java Database ConnectivityJDBC Java Database Connectivity
JDBC Java Database Connectivity
 
Local Storage for Web Applications
Local Storage for Web ApplicationsLocal Storage for Web Applications
Local Storage for Web Applications
 
Java Spring framework, Dependency Injection, DI, IoC, Inversion of Control
Java Spring framework, Dependency Injection, DI, IoC, Inversion of ControlJava Spring framework, Dependency Injection, DI, IoC, Inversion of Control
Java Spring framework, Dependency Injection, DI, IoC, Inversion of Control
 

Destaque

Telephony with OpenShift Twilio and MongoDB
Telephony with OpenShift Twilio and MongoDBTelephony with OpenShift Twilio and MongoDB
Telephony with OpenShift Twilio and MongoDB
Mark Atwood
 

Destaque (16)

Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
Scaling Symfony2 apps with RabbitMQ - Symfony UK MeetupScaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
 
Speed up your Symfony2 application and build awesome features with Redis
Speed up your Symfony2 application and build awesome features with RedisSpeed up your Symfony2 application and build awesome features with Redis
Speed up your Symfony2 application and build awesome features with Redis
 
Building real time applications with Symfony2
Building real time applications with Symfony2Building real time applications with Symfony2
Building real time applications with Symfony2
 
Intro to Angular.js & Zend2 for Front-End Web Applications
Intro to Angular.js & Zend2  for Front-End Web ApplicationsIntro to Angular.js & Zend2  for Front-End Web Applications
Intro to Angular.js & Zend2 for Front-End Web Applications
 
Juc boston2014.pptx
Juc boston2014.pptxJuc boston2014.pptx
Juc boston2014.pptx
 
PHP, RabbitMQ, and You
PHP, RabbitMQ, and YouPHP, RabbitMQ, and You
PHP, RabbitMQ, and You
 
Telephony with OpenShift Twilio and MongoDB
Telephony with OpenShift Twilio and MongoDBTelephony with OpenShift Twilio and MongoDB
Telephony with OpenShift Twilio and MongoDB
 
What RabbitMQ Can Do For You (Nomad PHP May 2014)
What RabbitMQ Can Do For You (Nomad PHP May 2014)What RabbitMQ Can Do For You (Nomad PHP May 2014)
What RabbitMQ Can Do For You (Nomad PHP May 2014)
 
Working with Asynchronous Events
Working with Asynchronous EventsWorking with Asynchronous Events
Working with Asynchronous Events
 
Asynchronous processing with PHP and Symfony2. Do it simple
Asynchronous processing with PHP and Symfony2. Do it simpleAsynchronous processing with PHP and Symfony2. Do it simple
Asynchronous processing with PHP and Symfony2. Do it simple
 
Scaling applications with RabbitMQ at SunshinePHP
Scaling applications with RabbitMQ   at SunshinePHPScaling applications with RabbitMQ   at SunshinePHP
Scaling applications with RabbitMQ at SunshinePHP
 
Interoperability With RabbitMq
Interoperability With RabbitMqInteroperability With RabbitMq
Interoperability With RabbitMq
 
Rationally boost your symfony2 application with caching tips and monitoring
Rationally boost your symfony2 application with caching tips and monitoringRationally boost your symfony2 application with caching tips and monitoring
Rationally boost your symfony2 application with caching tips and monitoring
 
Integrating RabbitMQ with PHP
Integrating RabbitMQ with PHPIntegrating RabbitMQ with PHP
Integrating RabbitMQ with PHP
 
2016 Digital predictions for marketing, tech, pop culture and everything in b...
2016 Digital predictions for marketing, tech, pop culture and everything in b...2016 Digital predictions for marketing, tech, pop culture and everything in b...
2016 Digital predictions for marketing, tech, pop culture and everything in b...
 
Build Features, Not Apps
Build Features, Not AppsBuild Features, Not Apps
Build Features, Not Apps
 

Semelhante a Theres a rabbit on my symfony

Visualizations of Spatial and Social Data
Visualizations of Spatial and Social DataVisualizations of Spatial and Social Data
Visualizations of Spatial and Social Data
interface2011
 
Applying operations culture to everything
Applying operations culture to everythingApplying operations culture to everything
Applying operations culture to everything
Theo Schlossnagle
 
Deployment presentation
Deployment presentationDeployment presentation
Deployment presentation
Corey Purcell
 

Semelhante a Theres a rabbit on my symfony (20)

How Lanyrd uses Twitter
How Lanyrd uses TwitterHow Lanyrd uses Twitter
How Lanyrd uses Twitter
 
Introducing Sencha Touch 2
Introducing Sencha Touch 2Introducing Sencha Touch 2
Introducing Sencha Touch 2
 
A importância dos dados em sua arquitetura... uma visão muito além do SQL Ser...
A importância dos dados em sua arquitetura... uma visão muito além do SQL Ser...A importância dos dados em sua arquitetura... uma visão muito além do SQL Ser...
A importância dos dados em sua arquitetura... uma visão muito além do SQL Ser...
 
High Availability Server Apps
High Availability Server AppsHigh Availability Server Apps
High Availability Server Apps
 
ActiveRain Univerity Link Class
ActiveRain Univerity Link ClassActiveRain Univerity Link Class
ActiveRain Univerity Link Class
 
The State of Web Typography
The State of Web TypographyThe State of Web Typography
The State of Web Typography
 
Testing distributed, complex web applications
Testing distributed, complex web applicationsTesting distributed, complex web applications
Testing distributed, complex web applications
 
Minegems
MinegemsMinegems
Minegems
 
Visualizations of Spatial and Social Data
Visualizations of Spatial and Social DataVisualizations of Spatial and Social Data
Visualizations of Spatial and Social Data
 
Node js techtalksto
Node js techtalkstoNode js techtalksto
Node js techtalksto
 
Interact - How to create an App?
Interact - How to create an App?Interact - How to create an App?
Interact - How to create an App?
 
Applying operations culture to everything
Applying operations culture to everythingApplying operations culture to everything
Applying operations culture to everything
 
Sandro Zaccarini, Achive escape velocity
Sandro Zaccarini, Achive escape velocitySandro Zaccarini, Achive escape velocity
Sandro Zaccarini, Achive escape velocity
 
Introducing Ext GWT 3.0
Introducing Ext GWT 3.0Introducing Ext GWT 3.0
Introducing Ext GWT 3.0
 
City Camp - Wolverhampton presentation
City Camp - Wolverhampton presentationCity Camp - Wolverhampton presentation
City Camp - Wolverhampton presentation
 
Deployment presentation
Deployment presentationDeployment presentation
Deployment presentation
 
Blogs micro
Blogs microBlogs micro
Blogs micro
 
Pronk like you mean it
Pronk like you mean itPronk like you mean it
Pronk like you mean it
 
Re/wiring Brains · Andres Colmenares
Re/wiring Brains · Andres ColmenaresRe/wiring Brains · Andres Colmenares
Re/wiring Brains · Andres Colmenares
 
Evolution of the Mobile Experience
Evolution of the Mobile Experience Evolution of the Mobile Experience
Evolution of the Mobile Experience
 

Mais de Alvaro Videla

Rabbitmq Boot System
Rabbitmq Boot SystemRabbitmq Boot System
Rabbitmq Boot System
Alvaro Videla
 

Mais de Alvaro Videla (20)

Improvements in RabbitMQ
Improvements in RabbitMQImprovements in RabbitMQ
Improvements in RabbitMQ
 
Data Migration at Scale with RabbitMQ and Spring Integration
Data Migration at Scale with RabbitMQ and Spring IntegrationData Migration at Scale with RabbitMQ and Spring Integration
Data Migration at Scale with RabbitMQ and Spring Integration
 
RabbitMQ Data Ingestion at Craft Conf
RabbitMQ Data Ingestion at Craft ConfRabbitMQ Data Ingestion at Craft Conf
RabbitMQ Data Ingestion at Craft Conf
 
Unit Test + Functional Programming = Love
Unit Test + Functional Programming = LoveUnit Test + Functional Programming = Love
Unit Test + Functional Programming = Love
 
RabbitMQ Data Ingestion
RabbitMQ Data IngestionRabbitMQ Data Ingestion
RabbitMQ Data Ingestion
 
Dissecting the rabbit: RabbitMQ Internal Architecture
Dissecting the rabbit: RabbitMQ Internal ArchitectureDissecting the rabbit: RabbitMQ Internal Architecture
Dissecting the rabbit: RabbitMQ Internal Architecture
 
Introduction to RabbitMQ | Meetup at Pivotal Labs
Introduction to RabbitMQ | Meetup at Pivotal LabsIntroduction to RabbitMQ | Meetup at Pivotal Labs
Introduction to RabbitMQ | Meetup at Pivotal Labs
 
Writing testable code
Writing testable codeWriting testable code
Writing testable code
 
RabbitMQ Hands On
RabbitMQ Hands OnRabbitMQ Hands On
RabbitMQ Hands On
 
Rabbitmq Boot System
Rabbitmq Boot SystemRabbitmq Boot System
Rabbitmq Boot System
 
Cloud Foundry Bootcamp
Cloud Foundry BootcampCloud Foundry Bootcamp
Cloud Foundry Bootcamp
 
Cloud Messaging With Cloud Foundry
Cloud Messaging With Cloud FoundryCloud Messaging With Cloud Foundry
Cloud Messaging With Cloud Foundry
 
Taming the rabbit
Taming the rabbitTaming the rabbit
Taming the rabbit
 
Vertx
VertxVertx
Vertx
 
Código Fácil De Testear
Código Fácil De TestearCódigo Fácil De Testear
Código Fácil De Testear
 
Desacoplando aplicaciones
Desacoplando aplicacionesDesacoplando aplicaciones
Desacoplando aplicaciones
 
Messaging patterns
Messaging patternsMessaging patterns
Messaging patterns
 
Scaling Web Apps With RabbitMQ - Erlang Factory Lite
Scaling Web Apps With RabbitMQ - Erlang Factory LiteScaling Web Apps With RabbitMQ - Erlang Factory Lite
Scaling Web Apps With RabbitMQ - Erlang Factory Lite
 
Integrating php withrabbitmq_zendcon
Integrating php withrabbitmq_zendconIntegrating php withrabbitmq_zendcon
Integrating php withrabbitmq_zendcon
 
Scaling webappswithrabbitmq
Scaling webappswithrabbitmqScaling webappswithrabbitmq
Scaling webappswithrabbitmq
 

Último

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 

Último (20)

MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 

Theres a rabbit on my symfony

  • 1. There's a Rabbit on my Symfony RabbitMQ and Symfony2 Integration Álvaro Videla Symfony Live 2011 Thursday, March 3, 2011
  • 3. About Me • Development Manager at TheNetCircle.com • Blog: http://videlalvaro.github.com/ • Twitter: @old_sound Thursday, March 3, 2011
  • 4. About Me • Developer at Liip • Blog: http://videlalvaro.github.com/ • Twitter: @old_sound Thursday, March 3, 2011
  • 5. About Me Co-authoring RabbitMQ in Action http://bit.ly/rabbitmq Thursday, March 3, 2011
  • 6. Why Do I need RabbitMQ? Thursday, March 3, 2011
  • 8. Why Do I need Messaging? Thursday, March 3, 2011
  • 9. An Upload Picture Form as seen by: Thursday, March 3, 2011
  • 11. I don’t want to wait till your app resizes my image! Thursday, March 3, 2011
  • 13. Can we also notify the user friends when she uploads a new image? Thursday, March 3, 2011
  • 14. 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
  • 16. Dumb! You’re delivering full size images! The bandwidth bill has tripled! Thursday, March 3, 2011
  • 17. Dumb! You’re delivering full size images! The bandwidth bill has tripled! We need this fixed for yesterday! Thursday, March 3, 2011
  • 18. The Developer in the other team Thursday, March 3, 2011
  • 19. I need to call your PHP stuff but from Python Thursday, March 3, 2011
  • 20. I need to call your PHP stuff but from Python And also Java starting next week Thursday, March 3, 2011
  • 23. Is there a solution? Thursday, March 3, 2011
  • 24. RabbitMQ & AMQP Thursday, March 3, 2011
  • 26. AMQP • Advanced Message Queuing Protocol • Suits Interoperability • Completely Open Protocol • Binary Protocol • AMQP Model • AMQP Wire Format Thursday, March 3, 2011
  • 27. AMQP Model • Exchanges • Message Queues • Bindings • Rules for binding them Thursday, March 3, 2011
  • 28. AMQP Wire Protocol • Functional Layer • Transport Layer Thursday, March 3, 2011
  • 29. 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
  • 30. Exchange Types • Fanout • Direct • Topic Thursday, March 3, 2011
  • 35. Usage Scenarios • Batch Processing Thursday, March 3, 2011
  • 36. Usage Scenarios • Batch Processing • Image Uploading Thursday, March 3, 2011
  • 37. Usage Scenarios • Batch Processing • Image Uploading • Distributed Logging Thursday, March 3, 2011
  • 38. Scenario Batch Processing Thursday, March 3, 2011
  • 40. Requirements • Generate XML Thursday, March 3, 2011
  • 41. Requirements • Generate XML • Distribution Over a Cluster Thursday, March 3, 2011
  • 42. Requirements • Generate XML • Distribution Over a Cluster • Elasticity - Add/Remove new workers Thursday, March 3, 2011
  • 43. Requirements • Generate XML • Distribution Over a Cluster • Elasticity - Add/Remove new workers • No Code Changes Thursday, March 3, 2011
  • 45. 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
  • 46. 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
  • 47. 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
  • 48. 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
  • 49. 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
  • 50. 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
  • 51. 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
  • 52. 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
  • 53. 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
  • 54. 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
  • 55. 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
  • 56. 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
  • 57. 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
  • 58. Scenario Upload Pictures Thursday, March 3, 2011
  • 60. Requirements • Upload Picture Thursday, March 3, 2011
  • 61. Requirements • Upload Picture • Reward User Thursday, March 3, 2011
  • 62. Requirements • Upload Picture • Reward User • Notify User Friends Thursday, March 3, 2011
  • 63. Requirements • Upload Picture • Reward User • Notify User Friends • Resize Picture Thursday, March 3, 2011
  • 64. Requirements • Upload Picture • Reward User • Notify User Friends • Resize Picture • No Code Changes Thursday, March 3, 2011
  • 68. 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
  • 69. 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
  • 70. 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
  • 71. 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
  • 72. 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
  • 73. 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
  • 74. 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
  • 75. 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
  • 76. 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
  • 77. 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
  • 78. 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
  • 79. 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
  • 80. 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
  • 81. 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
  • 82. 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
  • 83. 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
  • 84. Scenario Distributed Logging Thursday, March 3, 2011
  • 86. Requirements • Several Web Servers Thursday, March 3, 2011
  • 87. Requirements • Several Web Servers • Logic Separated by Module/Action Thursday, March 3, 2011
  • 88. Requirements • Several Web Servers • Logic Separated by Module/Action • Several Log Levels: Thursday, March 3, 2011
  • 89. Requirements • Several Web Servers • Logic Separated by Module/Action • Several Log Levels: • Info, Warning, Error Thursday, March 3, 2011
  • 90. 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
  • 96. 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
  • 97. 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
  • 98. 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
  • 99. 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
  • 100. Consumer Code Get messages sent by host: server1 Thursday, March 3, 2011
  • 101. 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
  • 102. 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
  • 103. 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
  • 104. 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
  • 105. Consumer Code Get all error messages Thursday, March 3, 2011
  • 106. 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
  • 107. 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
  • 108. 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
  • 109. 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
  • 112. RabbitMQ Bundle Goal: To be easy to use Thursday, March 3, 2011
  • 113. RabbitMQ Bundle Publish a Message: $msg = array('user_id' => 1235, 'image_path' => '/path/to/new/ pic.png'); $this->get('rabbitmq.upload_picture_producer')-> publish(serialize($msg)); Thursday, March 3, 2011
  • 114. RabbitMQ Bundle Consume a Message: $ ./app/console_dev rabbitmq:consumer -m 1 upload_picture Thursday, March 3, 2011
  • 115. RabbitMQ Bundle Consume 50 Messages: $ ./app/console_dev rabbitmq:consumer -m 50 upload_picture Thursday, March 3, 2011
  • 116. RabbitMQ Bundle Consume infinite* Messages: $ ./app/console_dev rabbitmq:consumer -m -1 upload_picture *messages may not be infinite Thursday, March 3, 2011
  • 117. RabbitMQ Bundle Configuration: # app/config/config.yml rabbitmq.config: connections: default: host: 'localhost' port: 5672 user: 'guest' password: 'guest' vhost: '/' Thursday, March 3, 2011
  • 118. RabbitMQ Bundle Configuration: # app/config/config.yml rabbitmq.config: connections: ... producers: upload_picture: connection: default exchange_options: {name: 'upload-picture', type: direct} Thursday, March 3, 2011
  • 119. RabbitMQ Bundle Configuration: # app/config/config.yml rabbitmq.config: connections: ... consumers: upload_picture: connection: default exchange_options: {name: 'upload-picture', type: direct} queue_options: {name: 'upload-picture'} callback: upload_picture_service Thursday, March 3, 2011
  • 120. RabbitMQ Bundle Using a Producer: 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)); ... } Thursday, March 3, 2011
  • 121. RabbitMQ Bundle Consumer Class: class UploadPictureConsumer extends ContainerAware implements ConsumerInterface { public function execute($msg) { // Process picture upload. // $msg will be what was published // from the Controller. } } Thursday, March 3, 2011
  • 122. RabbitMQ Bundle Recap: Thursday, March 3, 2011
  • 123. RabbitMQ Bundle Recap: • Add an entry for the consumer/producer in the configuration. Thursday, March 3, 2011
  • 124. RabbitMQ Bundle Recap: • Add an entry for the consumer/producer in the configuration. • Implement your Callback. Thursday, March 3, 2011
  • 125. RabbitMQ Bundle Recap: • Add an entry for the consumer/producer in the configuration. • Implement your Callback. • Start the consumer from the CLI. Thursday, March 3, 2011
  • 126. RabbitMQ Bundle Recap: • Add an entry for the consumer/producer in the configuration. • Implement your Callback. • Start the consumer from the CLI. • Add code to publish messages. Thursday, March 3, 2011
  • 127. RabbitMQ Bundle There’s more: Thursday, March 3, 2011
  • 128. RabbitMQ Bundle There’s more: • RPC clients and servers Thursday, March 3, 2011
  • 129. RabbitMQ Bundle There’s more: • RPC clients and servers • Anonymous consumers Thursday, March 3, 2011
  • 130. RabbitMQ Bundle There’s more: • RPC clients and servers • Anonymous consumers • Parallel RPC Thursday, March 3, 2011
  • 131. RabbitMQ Bundle Fork it at http://github.com/videlalvaro/RabbitMqBundle Thursday, March 3, 2011
  • 133. RabbitMQ • Enterprise Messaging System • Open Source MPL • Written in Erlang/OTP • Commercial Support Thursday, March 3, 2011
  • 134. 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
  • 135. Client Libraries • Java • .NET/C# • Erlang • Ruby, Python, PHP, Perl, AS3, Lisp, Scala, Clojure, Haskell Thursday, March 3, 2011
  • 136. 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
  • 137. One Setup for HA Thursday, March 3, 2011
  • 139. Conclusion • Flexibility Thursday, March 3, 2011
  • 140. Conclusion • Flexibility • Scalability Thursday, March 3, 2011
  • 141. Conclusion • Flexibility • Scalability • Interoperability Thursday, March 3, 2011
  • 142. Conclusion • Flexibility • Scalability • Interoperability • Reduce Ops Thursday, March 3, 2011
  • 144. 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