Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

81
Scaling Symfony2 apps with RabbitMQ

description

Slides from my talk at Symfony UK Meetup. London, 20 Aug 2014. http://twitter.com/cakper Video: https://www.youtube.com/watch?v=cha92Og9M5A

Transcript of Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Page 1: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Scaling Symfony2 apps

with RabbitMQ

Page 2: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Kacper Gunia @cakper Software Engineer @SensioLabsUK

Symfony Certified Developer

PHPers Silesia @PHPersPL

Page 3: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Agenda

❖What is RabbitMQ!❖How to communicate with it from PHP!❖How to integrate it with Symfony!❖Diving into details!❖Demo

Page 4: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Why would I need Messaging?

Page 5: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Use Cases

❖ Offloading / Background jobs!❖ Integration !❖ Scaling!❖ Queueing!❖ Scheduling!❖ Events

Page 6: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Message-oriented Middleware

“(…) allows distributed applications !to communicate and exchange data !by sending and receiving messages”

http://docs.oracle.com/cd/E19316-01/820-6424/aeraq/index.html

Page 7: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

What is inside a Rabbit?

Page 8: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

http://madamtruffle.deviantart.com/art/What-­‐is-­‐inside-­‐a-­‐rabbit-­‐81036248

Page 9: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

What is inside the RabbitMQ?

Page 10: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Message Broker

Page 11: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

AMQP

Page 12: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Erlang

Page 13: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Interoperability

❖ PHP!❖ Clojure!❖ Erlang!❖ Java!❖ Perl!❖ Python!❖ Ruby

❖ C#!❖ JavaScript!❖ C/C++!❖ Go!❖ Lisp!❖ Haskell!❖ …

Page 14: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

How does it work?

Page 15: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Broker

Bindings

Producer Exchange

Queue

Queue

Consumer

Consumer

Consumer

Consumer

Page 16: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Producer

Producer

Page 17: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Exchange

Exchange

Page 18: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Direct Exchange

Exchange Queue

Page 19: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Fanout Exchange

Exchange

Queue

Queue

Page 20: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Topic Exchange

#.error

#.warning, log.*

*.mobile.*

log.error

log.sql.warning

log.mobile.error

Page 21: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

“.” - word separator

Page 22: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

“#” - prefix/suffix wildcard

Page 23: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

“*” - word wildcard

Page 24: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Bindings

Bindings

Exchange

Queue

Queue

Page 25: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Queue

Queue

Page 26: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Consumer

Consumer

Page 27: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

How to feed Rabbit from PHP?

Page 28: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

PHP libraries and tools

❖ php-amqplib!❖ PECL AMQP !❖ amqphp!❖ VorpalBunny!❖ Thumper!❖ CAMQP

Page 29: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Declare queue$connection  =  new  AMQPConnection                    ('localhost',  5672,  'guest',  'guest');  $channel  =  $connection-­‐>channel();  !

$channel-­‐>queue_declare                    ('hello',  false,  false,  false,  false);  !

/**  Your  stuff  */  !

$channel-­‐>close();  $connection-­‐>close();

Page 30: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Producer

$msg  =  new  AMQPMessage('Hello  World!');  $channel-­‐>basic_publish($msg,  '',  'hello');  !

echo  "  [x]  Sent  'Hello  World!'\n";

Page 31: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Consumer$callback  =  function($msg)  {          echo  '  [x]  Received  ',  $msg-­‐>body,  "\n";  };  !

$channel-­‐>basic_consume    ('hello',  '',  false,  true,  false,  false,  $callback);  !

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

Page 32: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

RabbitMQ & Symfonyhttps://secure.flickr.com/photos/8725928@N02/9657136424

Page 33: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Step 1

Page 34: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Install RabbitMQ Bundle

composer  require  “oldsound/rabbitmq-­‐bundle  1.5.*”

Page 35: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Step 2

Page 36: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Enable bundle in Kernel

public  function  registerBundles()  {        $bundles  =[            (…)              new  OldSound\RabbitMqBundle\OldSoundRabbitMqBundle()        ];  }

Page 37: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Step 3

Page 38: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Say thanks to @old_sound :)

Page 39: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Step 4

Page 40: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Get rid off manual configuration

old_sound_rabbit_mq:          connections:                  default:                          host:          'localhost'                          port:          5672                          user:          'guest'                          password:  'guest'                          vhost:        '/'                          lazy:          false

Page 41: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Get rid off manual configuration

producers:          hello_world:                  connection:              default                  exchange_options:  {name:  'hello',  type:  direct}  consumers:          hello_world:                  connection:              default                  exchange_options:  {name:  'hello',  type:  direct}                  queue_options:        {name:  'hello'}                  callback:                  hello_world_service

Page 42: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Get rid off manual configuration

producers:          hello_world:                  connection:              default                  exchange_options:  {name:  'hello',  type:  direct}  consumers:          hello_world:                  connection:              default                  exchange_options:  {name:  'hello',  type:  direct}                  queue_options:        {name:  'hello'}                  callback:                  hello_world_service

Page 43: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Step 5

Page 44: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Produce some data

public  function  indexAction($name)  {          $this          -­‐>get('old_sound_rabbit_mq.hello_world_producer')          -­‐>publish($name);  }

Page 45: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Step 6

Page 46: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Implement consumer

class  HelloWorldConsumer  implements  ConsumerInterface  {          public  function  execute(AMQPMessage  $msg)          {                  echo  "Hello  $msg-­‐>body!".PHP_EOL;          }  }

Page 47: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Step 7

Page 48: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Configure Service Container

services:          hello_world_service:                  class:  Cakper\HelloWorldConsumer

Page 49: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Step 8

Page 50: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Run the Consumer

./app/console  rabbitmq:consumer  hello_world

Page 51: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Nailed it!

Page 52: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Diving intohttps://secure.flickr.com/photos/toms/159393358

Page 53: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Producers

Page 54: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Custom producer class

producers:          hello_world:                  connection:              default                  exchange_options:  {name:  'hello',  type:  direct}                  class:                        Cakper\HelloProducer

Page 55: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Custom producer class

class  HelloProducer  extends  Producer  {          public  function  publish($msgBody,  …)          {                  $msgBody  =  serialize($msgBody);  !

               parent::publish($msgBody,  …);          }  }  

Page 56: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Set content type

function  __construct()  {          $this-­‐>setContentType('application/json');  }  !

public  function  publish($msgBody,  …)  {          parent::publish(json_encode($msgBody),  …);  }

Page 57: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Consumers

Page 58: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Re-queue message

public  function  execute(AMQPMessage  $msg)  {          if  ('cakper'  ===  $msg-­‐>body)  {                  return  false;          }  !

       echo  "Hello  $msg-­‐>body!".PHP_EOL;  }

Page 59: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Idle timeouts

consumers:          hello_world:                  connection:              default                  exchange_options:  {name:  'hello',  type:  direct}                  queue_options:        {name:  'hello'}                  callback:                  hello_world_service                  idle_timeout:          180

Page 60: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Limit number of messages

./app/console  rabbitmq:consumer  hello_world  -­‐m  10

Page 61: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Quality of Service

qos_options:          prefetch_size:      0          prefetch_count:    0..65535          global:                    false/true

Page 62: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Exchanges

Page 63: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Exchange options

exchange_options:          name:                                  ~          type:                                  direct/fanout/topic          durable:                            true/false

Page 64: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Queues

Page 65: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Queue options

queue_options:          name:                                  ~          durable:                            true/false          arguments:                  'x-­‐message-­‐ttl':  ['I',  20000]          routing_keys:              -­‐  'logs.sql.#'              -­‐  '*.error'  

Page 66: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Purge queue

./app/console  rabbitmq:purge  -­‐-­‐no-­‐confirmation  hello

Page 67: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Connection

Page 68: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Make it lazy!

old_sound_rabbit_mq:          connections:                  default:                          host:          'localhost'                          port:          5672                          user:          'guest'                          password:  'guest'                          vhost:        '/'                          lazy:          true

Page 69: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Setup

Page 70: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Setup Fabric

./app/console  rabbitmq:setup-­‐fabric  !

producers:          upload_picture:              auto_setup_fabric:  false  consumers:          upload_picture:              auto_setup_fabric:  false

Page 71: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Multiple consumers

Page 72: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Multiple consumersmultiple_consumers:          hello:                  connection:              default                  exchange_options:  {name:  'hello',  type:  direct}                  queues:                          hello-­‐vip:                                  name:          hello_vip                                  callback:  hello_vip_world_service                                  routing_keys:                                          -­‐  vip                          hello-­‐regular:                                  name:          hello_regular                                  callback:  hello_regular_world_service

Page 73: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Anonymous Consumers

Page 74: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Anonymous Consumer

producers:          hello:                  connection:              default                  exchange_options:  {name:  'hello',  type:  topic}

Page 75: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Anonymous Consumer

anon_consumers:          hello:                  connection:              default                  exchange_options:  {name:  'hello',  type:  topic}                  callback:                  hello_world_service

Page 76: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Anonymous Consumer

./app/console_dev  rabbitmq:anon-­‐consumer  -­‐r  '#.vip'  hello

Page 77: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Management console

Page 78: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
Page 79: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Demo time

Page 80: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Summary

❖ RabbitMQ is fast!❖ and reliable!❖ also language agnostic!❖ and easy to install and use!❖ gives you flexibility!❖ supports high-availability, clustering

Page 81: Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup

Kacper Gunia Software Engineer

Symfony Certified Developer

PHPers Silesia

Thanks!