SlideShare une entreprise Scribd logo
1  sur  98
RabbitMQ y Symfony
Agenda
• Introducción a RabbitMQ
• RabbitMQ y Symfony
• Rabbit en la vida real
• Problemas
Quien Soy
• CTO en chicplace.com
• Apasionado de la Web
• 8 años en PHP
• Whovian y Aerotrastornado
¿Que es RabbitMQ?
Sistema de Colas
¿Que es RabbitMQ?
• Sistema de mensajería
• Implementa AMQP
• Robusto
• Facil de Usar
¿Que he de saber?
Mensajes
• Body
• Body es lo que nosotros
decidamos (json/serialize/
binario/txt…)
• Header:
• Info para el broker
• Info para la aplicación
Mensajes
• Body
• Body es lo que nosotros
decidamos (json/serialize/
binario/txt…)
• Header:
• Info para el broker
• Info para la aplicación
Header
Content type
Content Encoding
Routing key
Delivery Mode
Message Priority
Message publishing timestamp
Expiration period
App Id
Body
{
"id": 0,
"guid":
"2cbe2352-6d0e-430b-8faf-122eea44ebf3",
"isActive": false,
"balance": "$3,243.34",
"picture": "http://placehold.it/
32x32",
"age": 25,
"eyeColor": "blue",
"name": "Lawanda Serrano",
"gender": "female",
"company": "ELEMANTRA",
"email":
"lawandaserrano@elemantra.com",
"phone": "+1 (827) 534-2331”
}
Colas
• Mensajes esperan a ser consumidos
• FIFO
• Persistente
• Exclusiva
• Autoborrado
• Round Robin
Exchanges
• Donde se envían mensajes
• Enrutar
• Tipos:
• Direct
• Fanout
• Topic
• Autoborrado
Direct Exchange
• Una cola C se subscribe a un
exchange con la clave X
• Nuevo mensaje con la clave Y
• Si X = Y enrutar a cola C
Fanout Exchange
• El exchange enrutará el
mensaje a todas las colas
subscritas
Topic Exchange
• Un mensaje es enrulado a
una o varias colas
dependiendo de un match
con un patrón.
https://access.redhat.com/site/documentation/en-US/Red_Hat_Enterprise_MRG/1.1/html/Messaging_User_Guide/chap-Messaging_User_Guide-
Exchanges.html
Persistencia
• ¿Que pasa cuando palma?
• Podemos guardar en disco la estructura
• Podemos guardar en disco los mensajes
• Si guardamos los mensajes debemos guardar la
estructura
https://www.youtube.com/watch?v=G1UKDccxj00
https://www.youtube.com/watch?v=G1UKDccxj00
Saber Más
Saber Más
Saber Más
Saber Más
http://www.rabbitmq.com/
Saber Más
http://www.rabbitmq.com/
http://www.slideshare.net/old_sound
Saber Más
http://www.rabbitmq.com/
http://www.slideshare.net/old_sound
http://www.rabbitmq.com/resources/specs/amqp0-9-1.pdf
Saber Más
http://www.rabbitmq.com/
http://www.slideshare.net/old_sound
http://www.rabbitmq.com/resources/specs/amqp0-9-1.pdf
http://wedevelopers.com/2014/06/23/we-developers-034-rabbitmq/
https://www.youtube.com/watch?v=jxTngPDNqk8
https://www.youtube.com/watch?v=jxTngPDNqk8
RabbitMQ y Symfony
RabbitMQ y Symfony
RabbitMQ y Symfony
• RabbitMQBundle (https://github.com/videlalvaro/rabbitmqbundle)
RabbitMQ y Symfony
• RabbitMQBundle (https://github.com/videlalvaro/rabbitmqbundle)
• Basado en PhpAmqpLib
RabbitMQ y Symfony
• RabbitMQBundle (https://github.com/videlalvaro/rabbitmqbundle)
• Basado en PhpAmqpLib
• Creación de Consumidores/Productores sencilla.
RabbitMQ y Symfony
• RabbitMQBundle (https://github.com/videlalvaro/rabbitmqbundle)
• Basado en PhpAmqpLib
• Creación de Consumidores/Productores sencilla.
• Configuración de rabbit sencilla.
RabbitMQ y Symfony
• RabbitMQBundle (https://github.com/videlalvaro/rabbitmqbundle)
• Basado en PhpAmqpLib
• Creación de Consumidores/Productores sencilla.
• Configuración de rabbit sencilla.
• No excesivamente estable. Nuevas funcionalidades constantes
RabbitMQ y Symfony
• RabbitMQBundle (https://github.com/videlalvaro/rabbitmqbundle)
• Basado en PhpAmqpLib
• Creación de Consumidores/Productores sencilla.
• Configuración de rabbit sencilla.
• No excesivamente estable. Nuevas funcionalidades constantes
• PhpAmqpLib (https://github.com/videlalvaro/php-amqplib)
RabbitMQ y Symfony
• RabbitMQBundle (https://github.com/videlalvaro/rabbitmqbundle)
• Basado en PhpAmqpLib
• Creación de Consumidores/Productores sencilla.
• Configuración de rabbit sencilla.
• No excesivamente estable. Nuevas funcionalidades constantes
• PhpAmqpLib (https://github.com/videlalvaro/php-amqplib)
• La libreria de referencia.
RabbitMQ y Symfony
• RabbitMQBundle (https://github.com/videlalvaro/rabbitmqbundle)
• Basado en PhpAmqpLib
• Creación de Consumidores/Productores sencilla.
• Configuración de rabbit sencilla.
• No excesivamente estable. Nuevas funcionalidades constantes
• PhpAmqpLib (https://github.com/videlalvaro/php-amqplib)
• La libreria de referencia.
• No te da muchas facilidades
RabbitMQ y Symfony
composer require oldsound/rabbitmq-bundle:1.3.*
Instalación
<?php

public function registerBundles()

{

$bundles = array(

new OldSoundRabbitMqBundleOldSoundRabbitMqBundle(),

);



return $bundles;

}
old_sound_rabbit_mq:
connections:
default:
host: 'localhost'
port: 5672
user: 'guest'
password: 'guest'
vhost: '/'
lazy: true
producers:
make_thumbnail:
connection: default
exchange_options:
name: 'make-thumbnail-exchange'
type: direct
durable: true
auto_delete: false
consumers:
make_thumbnail:
connection: default
exchange_options:
name: 'make-thumbnail-exchange'
type: direct
durable: true
auto_delete: false
queue_options: {name: 'make-thumbnail-queue',durable: true}
callback: solilokiam.rabbitmq.make_thumbnail_consumer
RabbitMQ y Symfony
Configuración
old_sound_rabbit_mq:
connections:
default:
host: 'localhost'
port: 5672
user: 'guest'
password: 'guest'
vhost: '/'
lazy: true
producers:
make_thumbnail:
connection: default
exchange_options:
name:
type: direct
durable: true
auto_delete: false
consumers:
make_thumbnail:
connection: default
exchange_options:
name:
type: direct
durable: true
auto_delete: false
queue_options: {
callback: solilokiam.rabbitmq.make_thumbnail_consumer
RabbitMQ y Symfony
Configuración
old_sound_rabbit_mq:!
connections:!
default:!
host: 'localhost'!
port: 5672!
user: 'guest'!
password: 'guest'!
vhost: '/'!
lazy: true
old_sound_rabbit_mq:
connections:
default:
host: 'localhost'
port: 5672
user: 'guest'
password: 'guest'
vhost: '/'
lazy: true
producers:
make_thumbnail:
connection: default
exchange_options:
name:
type: direct
durable: true
auto_delete: false
consumers:
make_thumbnail:
connection: default
exchange_options:
name:
type: direct
durable: true
auto_delete: false
queue_options: {
callback: solilokiam.rabbitmq.make_thumbnail_consumer
RabbitMQ y Symfony
Configuración
producers:
make_thumbnail:
connection: default
exchange_options:
name: 'make-thumbnail-exchange'
type: direct
durable: true
auto_delete: false
old_sound_rabbit_mq:
connections:
default:
host: 'localhost'
port: 5672
user: 'guest'
password: 'guest'
vhost: '/'
lazy: true
producers:
make_thumbnail:
connection: default
exchange_options:
name:
type: direct
durable: true
auto_delete: false
consumers:
make_thumbnail:
connection: default
exchange_options:
name:
type: direct
durable: true
auto_delete: false
queue_options: {
callback: solilokiam.rabbitmq.make_thumbnail_consumer
RabbitMQ y Symfony
Configuración
consumers:
make_thumbnail:
connection: default
exchange_options:
name: 'make-thumbnail-exchange'
type: direct
durable: true
auto_delete: false
queue_options: {name: 'make-thumbnail-queue',durable: true}
callback: solilokiam.rabbitmq.make_thumbnail_consumer
RabbitMQ y Symfony
protected function execute(InputInterface $input, OutputInterface $output)
{
$width = $input->getOption('width')?$input->getOption('width'):300;
$height = $input->getOption('height')?$input->getOption('height'):300;
!
$finder = new Finder();
$finder
->files()
->name('*.jpg')
->name('*.png')
->name('*.gif')
->in($input->getArgument('origin'));
!
foreach($finder as $file)
{
$messageArray = array(
'original_image_path' => $file->getRealPath(),
'destination_image_path' => $input->getArgument('destination').'/'.$file->getFileName(),
'width' => $width,
'height' => $height
);
!
$this->getContainer()->get('old_sound_rabbit_mq.make_thumbnail_producer')
->setContentType('application/json')
->setDeliveryMode(2)
->publish(json_encode($messageArray));
}
}
RabbitMQ y Symfony
protected
{
$width
$height
!
$finder
$finder
!
foreach
{
);
!
}
}
$this->getContainer()
->get('old_sound_rabbit_mq.make_thumbnail_producer')
->setContentType('application/json')
->setDeliveryMode(2)
->publish(json_encode($messageArray));
https://www.youtube.com/watch?v=zadD8X9MtUg
https://www.youtube.com/watch?v=zadD8X9MtUg
RabbitMQ y Symfony
Consumidor
class MakeThumbnailConsumer implements ConsumerInterface
{
public function execute(AMQPMessage $msg)
{
$data = json_decode($msg->body);
$imagine = new Imagine();
try
{
$imagine->open($data['original_image_path'])
->resize(new Box($data['width'],$data['height']))
->save($data['destination_image_path']);
} catch(Exception $e) {
return false;
}
return true;
}
!
}
RabbitMQ y Symfony
app/console rabbitmq:consumer make_thumbnail
app/console rabbitmq:consumer make_thumbnail -m 10
app/console rabbitmq:consumer make_thumbnail -l 256
app/console rabbitmq:consumer make_thumbnail -w
app/console rabbitmq:purge --no-confirmation make_thumbnail
¿Para que sirve RabbitMQ?
• Procesos en batch.
• Desacoplar.
• Eventos asíncronos
• Logs
Problemas de la vida real
Velocidad
• Los productores producen a más velocidad de la que
los consumidores son capaces de consumir.
• Las colas se llenan
• Optimiza el consumidor• Arranca más consumidores
Problema
Solución
Diferencias de Velocidad
Problema
• Sobre la misma cola un consumidor procesa más
mensajes que el otro.
• Un consumidor acaba ocioso y el otro tiene mensajes
pendientes
Diferencias de Velocidad
http://www.cloudamqp.com/
Diferencias de Velocidad
Causa
• Algoritmo de round robin de las colas.
http://www.cloudamqp.com/
Diferencias de Velocidad
Causa
• Algoritmo de round robin de las colas.
Mensaje1
Mensaje2
Mensaje3
Mensaje4
Mensaje5
Mensaje6
Productor
http://www.cloudamqp.com/
Diferencias de Velocidad
Causa
• Algoritmo de round robin de las colas.
Mensaje1
Mensaje2
Mensaje3
Mensaje4
Mensaje5
Mensaje6
Productor
http://www.cloudamqp.com/
Diferencias de Velocidad
Causa
• Algoritmo de round robin de las colas.
Mensaje1
Mensaje2
Mensaje3
Mensaje4
Mensaje5
Mensaje6
Productor
http://www.cloudamqp.com/
Diferencias de Velocidad
Causa
• Algoritmo de round robin de las colas.
Mensaje1
Mensaje2
Mensaje3
Mensaje4
Mensaje5
Mensaje6
Productor
http://www.cloudamqp.com/
Diferencias de Velocidad
Causa
• Algoritmo de round robin de las colas.
Mensaje1
Mensaje2
Mensaje3
Mensaje4
Mensaje5
Mensaje6
Productor
Mensaje1
Mensaje3
Mensaje5
Consumidor 1
Mensaje2
Mensaje4
Mensaje6
Consumidor 2
http://www.cloudamqp.com/
Diferencias de Velocidad
Diferencias de Velocidad
Solución
• channel.basic_qos(prefetch_count=1)
Diferencias de Velocidad
Solución
• channel.basic_qos(prefetch_count=1)
consumers:
make_thumbnail:
connection: default
exchange_options:
name: 'make-thumbnail-exchange'
type: direct
durable: true
auto_delete: false
queue_options: {name: 'make-thumbnail-queue',durable: true}
callback: solilokiam.rabbitmq.make_thumbnail_consumer
qos_options: {prefetch_size=0, prefetch_count: 1, global: false}
Pierdo la conexión
Problema
• RabbitMQ cierra la conexión TCP cada x minutos.
• Mi consumidor se queda colgado
Pierdo la conexión
• Hacer que el consumer muera al cabo de un tiempo de
inactividad.
consumers:
make_thumbnail:
connection: default
exchange_options:
name: 'make-thumbnail-exchange'
type: direct
durable: true
auto_delete: false
queue_options: {name: 'make-thumbnail-queue',durable: true}
callback: solilokiam.rabbitmq.make_thumbnail_consumer
idle_timeout: 60
Pierdo la conexión
Solución
• Hacer que el consumer muera al cabo de un tiempo de
inactividad.
consumers:
make_thumbnail:
connection: default
exchange_options:
name: 'make-thumbnail-exchange'
type: direct
durable: true
auto_delete: false
queue_options: {name: 'make-thumbnail-queue',durable: true}
callback: solilokiam.rabbitmq.make_thumbnail_consumer
idle_timeout: 60
Problemas de comunicación
Problema
• El formato de mensajes producidos no es entendido
por los consumidores.
• El formato de los mensajes cambia.
https://www.youtube.com/watch?v=9ITVzXB2DWY
https://www.youtube.com/watch?v=9ITVzXB2DWY
Problemas de comunicación
Solución
• Documentación/Comunicación/Normas
• Introducir un traductor de mensajes
public function execute(AMQPMessage $msg)
{
try
{
$makeThumbnailMsg = $this->translator($msg);
$imagine = new Imagine();
$imagine->open($makeThumbnailMsg->getOriginalImagePath())
->resize(new Box($makeThumbnailMsg->getWidth(),$makeThumbnailMsg->getHeight()))
->save($makeThumbnailMsg->getDestinationImagePath());
} catch(Exception $e) {
return false;
}
!
return true;
}
Problemas de comunicación
Problemas de comunicación
class MakeThumbnailTranslator implements TranslatorInterface
{
public function translateMessage($message)
{
$data = json_decode($message->body,true);
!
if(json_last_error() !== JSON_ERROR_NONE)
{
throw new Exception('WrongMessage');
}
!
$makeThumbnailMessage = new MakeThumbnailMessage();
$makeThumbnailMessage->setOriginalImagePath($data['original_image_path']);
$makeThumbnailMessage->setDestinationImagePath($data['destination_image_path']);
$makeThumbnailMessage->setWidth($data['width']);
$makeThumbnailMessage->setHeight($data['height']);
!
return $makeThumbnailMessage;
}
!
}
La importancia del orden
Problema
• Los mensajes han de ser consumidos en el mismo
orden que se han publicado.
• Quiero tener mas de un consumer para dar velocidad.
La importancia del orden
Solución
• Sección 4.7 protocolo AMQP: […]Specifically,
contents flowing through a single path within the
server will remain ordered For contents of a given
priority flowing through a single path, we define a
content processing path as consisting of one incoming
channel, one exchange, one queue, and one outgoing
channel.
La importancia del orden
Solución
Un consumer y punto
Organización
Problema
• Múltiples tipos de mensaje.
• Múltiples significados.
• Muchos consumers vs. Un consumer
• Muchos Exchanges vs. Un exchange
Organización
Solución
• Organizar los exchanges por afinidad.
• Una cola por exchange (direct o fanout)
• Todos los mensajes al mismo consumer
• Filtramos por type
public function execute(AMQPMessage $message)
{
if (!array_key_exists($message->get('type'), $this->workers)) {
return false;
}
!
return $this->workers[$message->get('type')]->doWork($message->body);
}
Organización
Solución
• Organizar los exchanges por afinidad.
• Utilizar el routing de RabbitMQ
• Un consumer por tipo de mensaje
• Una cola por tipo de mensaje
multiple_consumers:
make_thumbnail:
connection: default
exchange_options:
name: 'make-thumbnail-exchange'
type: direct
durable: true
auto_delete: false
queues:
make_thumbnail_video:
name: make-thumbnail-video
callback: solilokiam.rabbitmq.make_thumbnail_video
routing_keys:
- video
make_thumbnail_picture:
name: make-thumbnail-picture
callback: solilokiam.rabbitmq.make_thumbnail_picture
routing_keys:
- picture
make_thumbnail_log:
name: make-thumbnail-log
callback: solilokiam.rabbitmq.make_thumbnail_log
Organización
Solución
multiple_consumers:
make_thumbnail:
connection: default
exchange_options:
name: 'make-thumbnail-exchange'
type: direct
durable: true
auto_delete: false
queues:
make_thumbnail_video:
name: make-thumbnail-video
callback: solilokiam.rabbitmq.make_thumbnail_video
routing_keys:
- video
make_thumbnail_picture:
name: make-thumbnail-picture
callback: solilokiam.rabbitmq.make_thumbnail_picture
routing_keys:
- picture
make_thumbnail_log:
name: make-thumbnail-log
callback: solilokiam.rabbitmq.make_thumbnail_log
Organización
Solución
composer require oldsound/rabbitmq-bundle:dev-master
app/console rabbitmq:multiple-consumer make_thumbnail
¿Donde esta la respuesta?
Problema
• Necesito una respuesta a los mensajes que lanzo.
• Quiero poder paralizar las llamadas.
• Lo quiero hacer con RabbitMQ.
¿Donde esta la respuesta?
Solución
rpc_clients:
string_reverser:
connection: default
rpc_servers:
string_reverse:
connection: default
callback: solilokiam.rabbitmq.string_reverser
qos_options: {prefetch_size: 0, prefetch_count: 1, global: false}
class StringReverser implements ConsumerInterface
{
protected $translator;
!
function __construct(TranslatorInterface $translator)
{
$this->translator = $translator;
}
!
public function execute(AMQPMessage $msg)
{
$stringReverseMessage = $this->translator->translateMessage($msg);
!
return strrev($stringReverseMessage->getString());
}
!
}
¿Donde esta la respuesta?
class StringReverser implements ConsumerInterface
{
protected $translator;
!
function __construct(TranslatorInterface $translator)
{
$this->translator = $translator;
}
!
public function execute(AMQPMessage $msg)
{
$stringReverseMessage = $this->translator->translateMessage($msg);
!
return strrev($stringReverseMessage->getString());
}
!
}
¿Donde esta la respuesta?
app/console rabbit:rpc-server string_reverse
¿Donde esta la respuesta?
protected function execute(InputInterface $input, OutputInterface $output)
{
$reversableString = $input->getArgument('reversable_string');
!
$message_array = array(
'string' => $reversableString
);
!
$requestIdentifier = microtime();
!
$client = $this->getContainer()->get('old_sound_rabbit_mq.string_reverser_rpc');
$client->addRequest(json_encode($message_array),'string_reverse',$requestIdentifier);
!
$replies=$client->getReplies();
!
$output->writeln($replies);
}
¿Donde esta la respuesta?
protected function execute(InputInterface $input, OutputInterface $output)
{
$reversableString = $input->getArgument('reversable_string');
!
$message_array = array(
'string' => $reversableString
);
!
$client = $this->getContainer()->get('old_sound_rabbit_mq.string_reverser_rpc');
!
$requestIdentifier = microtime();
!
$client->addRequest(json_encode($message_array),'string_reverse',$requestIdentifier);
!
$requestIdentifier2 = microtime();
!
$client->addRequest(json_encode($message_array),'string_capitalize',$requestIdentifier2);
!
$replies=$client->getReplies();
!
$output->writeln($replies[$requestIdentifier]);
$output->writeln($replies[$requestIdentifier2]);
}
Vamos a viajar
Vamos a viajar
Problema
• Nuestra aplicación esta repartida por varias Regiones
• Queremos buena latencia.
• Queremos que los mensajes se propaguen.
Vamos a viajar
Solución
• Federation
https://www.rabbitmq.com/federation.html
Vamos a viajar
https://www.rabbitmq.com/federation.html
Vamos a viajar
Vamos a viajar
Solución
• Shovel
• Se conecta a una cola en el broker de origen
• Consume el mensaje
• Publica el mensaje al broker de destino
[{rabbitmq_shovel,
[{shovels,
[{MyShovels1,
[{sources, [{broker,"amqp://guest:guest@Machine01/MyVHost"}]},
{destinations, [{broker, "amqp://guest:guest@Machine02/MyVHost"}]},
{queue, <<"MySourceQueue1">>},
{ack_mode, on_confirm},
{publish_properties, [{delivery_mode, 2}]},
{publish_fields, [{exchange, <<"MyDestExchange">>},
{routing_key, <<>>}]},
{reconnect_delay, 5}
]}
]
}]
}]
Vamos a viajar
Todavía quiero saber más
Todavía quiero saber más
Todavía quiero saber más
¿Preguntas?
https://www.youtube.com/watch?v=YZ85_Bg-1QU
¿Preguntas?
https://www.youtube.com/watch?v=YZ85_Bg-1QU
Muchas Gracias
@solilokiam
miquel@solilokiam.com

Contenu connexe

Tendances

Tendances (20)

Procedimento de instalação do Zabbix Proxy 3 no PFSense
Procedimento de instalação do Zabbix Proxy 3 no PFSenseProcedimento de instalação do Zabbix Proxy 3 no PFSense
Procedimento de instalação do Zabbix Proxy 3 no PFSense
 
Zabbix para iniciantes
Zabbix para iniciantesZabbix para iniciantes
Zabbix para iniciantes
 
Ccna Commands In 10 Minutes
Ccna Commands In 10 MinutesCcna Commands In 10 Minutes
Ccna Commands In 10 Minutes
 
Wireshark
WiresharkWireshark
Wireshark
 
Group Policy
Group PolicyGroup Policy
Group Policy
 
ACI Netflow 구성 가이드
ACI Netflow 구성 가이드ACI Netflow 구성 가이드
ACI Netflow 구성 가이드
 
Automating for Monitoring and Troubleshooting your Cisco IOS Network
Automating for Monitoring and Troubleshooting your Cisco IOS NetworkAutomating for Monitoring and Troubleshooting your Cisco IOS Network
Automating for Monitoring and Troubleshooting your Cisco IOS Network
 
Temperatura Zabbix Procedimento Temper Usb
Temperatura Zabbix Procedimento Temper UsbTemperatura Zabbix Procedimento Temper Usb
Temperatura Zabbix Procedimento Temper Usb
 
VXLAN BGP EVPN: Technology Building Blocks
VXLAN BGP EVPN: Technology Building BlocksVXLAN BGP EVPN: Technology Building Blocks
VXLAN BGP EVPN: Technology Building Blocks
 
Suricata
SuricataSuricata
Suricata
 
Nmap and metasploitable
Nmap and metasploitableNmap and metasploitable
Nmap and metasploitable
 
Sargent 6123
Sargent 6123Sargent 6123
Sargent 6123
 
Expo vlan
Expo vlan Expo vlan
Expo vlan
 
ONOS intent introduction
ONOS intent introductionONOS intent introduction
ONOS intent introduction
 
2017 Secure360 - Hacking SQL Server on Scale with PowerShell
2017 Secure360 - Hacking SQL Server on Scale with PowerShell2017 Secure360 - Hacking SQL Server on Scale with PowerShell
2017 Secure360 - Hacking SQL Server on Scale with PowerShell
 
Tn 310 vlan-trunking
Tn 310 vlan-trunkingTn 310 vlan-trunking
Tn 310 vlan-trunking
 
Igor Nicoli: External scripts O poder do Zabbix em suas mãos
Igor Nicoli: External scripts O poder do Zabbix em suas mãosIgor Nicoli: External scripts O poder do Zabbix em suas mãos
Igor Nicoli: External scripts O poder do Zabbix em suas mãos
 
Cisco switch commands cheat sheet
Cisco switch commands cheat sheetCisco switch commands cheat sheet
Cisco switch commands cheat sheet
 
Brkarc 3454 - in-depth and personal with the cisco nexus 2000 fabric extender...
Brkarc 3454 - in-depth and personal with the cisco nexus 2000 fabric extender...Brkarc 3454 - in-depth and personal with the cisco nexus 2000 fabric extender...
Brkarc 3454 - in-depth and personal with the cisco nexus 2000 fabric extender...
 
Microsoft Security Development Lifecycle
Microsoft Security Development LifecycleMicrosoft Security Development Lifecycle
Microsoft Security Development Lifecycle
 

En vedette

Sistema monitorización con Symfony2, RabbitMQ, MongoDB y ExtJS4
Sistema monitorización con Symfony2, RabbitMQ, MongoDB y ExtJS4Sistema monitorización con Symfony2, RabbitMQ, MongoDB y ExtJS4
Sistema monitorización con Symfony2, RabbitMQ, MongoDB y ExtJS4
Jordi Llonch
 
Premios a Safe abogados tu abogado a pie de calle premiol
Premios a Safe abogados tu abogado a pie de calle premiolPremios a Safe abogados tu abogado a pie de calle premiol
Premios a Safe abogados tu abogado a pie de calle premiol
Safe Abogados
 
Integración de Tecnología - 1er año ''B''
Integración de Tecnología - 1er año ''B''Integración de Tecnología - 1er año ''B''
Integración de Tecnología - 1er año ''B''
Mily489
 
Ritos del café
Ritos del caféRitos del café
Ritos del café
liligvidal
 

En vedette (20)

Rabbits, indians and... Symfony meets queueing brokers
Rabbits, indians and...  Symfony meets queueing brokersRabbits, indians and...  Symfony meets queueing brokers
Rabbits, indians and... Symfony meets queueing brokers
 
Detrás del Backend [phpDay 2015]
Detrás del Backend [phpDay 2015]Detrás del Backend [phpDay 2015]
Detrás del Backend [phpDay 2015]
 
PHP Barcelona Monthly Talk Feb 2015
PHP Barcelona Monthly Talk Feb 2015PHP Barcelona Monthly Talk Feb 2015
PHP Barcelona Monthly Talk Feb 2015
 
What RabbitMQ can do for you (phpnw14 Uncon)
What RabbitMQ can do for you (phpnw14 Uncon)What RabbitMQ can do for you (phpnw14 Uncon)
What RabbitMQ can do for you (phpnw14 Uncon)
 
Dealing with fear in legacy projects #PHPDS15
Dealing with fear in legacy projects #PHPDS15Dealing with fear in legacy projects #PHPDS15
Dealing with fear in legacy projects #PHPDS15
 
Joomla!day2013 Albacete Spain, Responsive, Adaptive y la tundra
Joomla!day2013 Albacete Spain, Responsive, Adaptive y la tundraJoomla!day2013 Albacete Spain, Responsive, Adaptive y la tundra
Joomla!day2013 Albacete Spain, Responsive, Adaptive y la tundra
 
Gearman and asynchronous processing in PHP applications
Gearman and asynchronous processing in PHP applicationsGearman and asynchronous processing in PHP applications
Gearman and asynchronous processing in PHP applications
 
PHPBarcelona Conference - Optimización aplicaciones PHP - Client side
PHPBarcelona Conference - Optimización aplicaciones PHP - Client sidePHPBarcelona Conference - Optimización aplicaciones PHP - Client side
PHPBarcelona Conference - Optimización aplicaciones PHP - Client side
 
Ecosistema de desarrollo en PHP con Docker y Ansible
Ecosistema de desarrollo en PHP con Docker y AnsibleEcosistema de desarrollo en PHP con Docker y Ansible
Ecosistema de desarrollo en PHP con Docker y Ansible
 
Steganography: Hiding your secrets with PHP
Steganography: Hiding your secrets with PHPSteganography: Hiding your secrets with PHP
Steganography: Hiding your secrets with PHP
 
From Legacy to DDD in PHP | Tech Talks | Privalia
From Legacy to DDD in PHP | Tech Talks | PrivaliaFrom Legacy to DDD in PHP | Tech Talks | Privalia
From Legacy to DDD in PHP | Tech Talks | Privalia
 
Sistema monitorización con Symfony2, RabbitMQ, MongoDB y ExtJS4
Sistema monitorización con Symfony2, RabbitMQ, MongoDB y ExtJS4Sistema monitorización con Symfony2, RabbitMQ, MongoDB y ExtJS4
Sistema monitorización con Symfony2, RabbitMQ, MongoDB y ExtJS4
 
Premios a Safe abogados tu abogado a pie de calle premiol
Premios a Safe abogados tu abogado a pie de calle premiolPremios a Safe abogados tu abogado a pie de calle premiol
Premios a Safe abogados tu abogado a pie de calle premiol
 
Actualidad Berriak 40
Actualidad Berriak 40Actualidad Berriak 40
Actualidad Berriak 40
 
Integración de Tecnología - 1er año ''B''
Integración de Tecnología - 1er año ''B''Integración de Tecnología - 1er año ''B''
Integración de Tecnología - 1er año ''B''
 
Simple Load Rebalancing For Distributed Hash Tables In Cloud
Simple Load Rebalancing For Distributed Hash Tables In CloudSimple Load Rebalancing For Distributed Hash Tables In Cloud
Simple Load Rebalancing For Distributed Hash Tables In Cloud
 
Snow Motion Graphic Portfolio
Snow Motion Graphic PortfolioSnow Motion Graphic Portfolio
Snow Motion Graphic Portfolio
 
Configuring Incoming Emai
Configuring Incoming EmaiConfiguring Incoming Emai
Configuring Incoming Emai
 
Händlerliste.pdf
Händlerliste.pdfHändlerliste.pdf
Händlerliste.pdf
 
Ritos del café
Ritos del caféRitos del café
Ritos del café
 

Similaire à RabbitMQ y Symfony

Scripting para Pentesters v1.0
Scripting para Pentesters v1.0Scripting para Pentesters v1.0
Scripting para Pentesters v1.0
wcuestas
 

Similaire à RabbitMQ y Symfony (20)

DeSymfony 2017 - Symfony en OpenSky
DeSymfony 2017 - Symfony en OpenSkyDeSymfony 2017 - Symfony en OpenSky
DeSymfony 2017 - Symfony en OpenSky
 
Symfony Parte 3
Symfony Parte 3Symfony Parte 3
Symfony Parte 3
 
Scripting para Pentesters v1.0
Scripting para Pentesters v1.0Scripting para Pentesters v1.0
Scripting para Pentesters v1.0
 
Symfony Parte 2
Symfony Parte 2Symfony Parte 2
Symfony Parte 2
 
Desymfony 2011 - Tutorial #1: Instalacion y primeros pasos
Desymfony 2011 - Tutorial #1: Instalacion y primeros pasosDesymfony 2011 - Tutorial #1: Instalacion y primeros pasos
Desymfony 2011 - Tutorial #1: Instalacion y primeros pasos
 
Adentrándonos al Framework Symfony
Adentrándonos al  Framework SymfonyAdentrándonos al  Framework Symfony
Adentrándonos al Framework Symfony
 
Desarrollando filtros para Kurento
Desarrollando filtros para KurentoDesarrollando filtros para Kurento
Desarrollando filtros para Kurento
 
Frontal avanzado y assetic
Frontal avanzado y asseticFrontal avanzado y assetic
Frontal avanzado y assetic
 
Frontal Avanzado y Assetic
Frontal Avanzado y AsseticFrontal Avanzado y Assetic
Frontal Avanzado y Assetic
 
Por qué Symfony2 es tan rápido
Por qué Symfony2 es tan rápidoPor qué Symfony2 es tan rápido
Por qué Symfony2 es tan rápido
 
BDD con Mink y Behat
BDD con Mink y BehatBDD con Mink y Behat
BDD con Mink y Behat
 
Taller
TallerTaller
Taller
 
App engine
App engineApp engine
App engine
 
Gestión Remota de Equipos con Python
Gestión Remota de Equipos con PythonGestión Remota de Equipos con Python
Gestión Remota de Equipos con Python
 
Introduction to Akamon software arquitecture for MPWAR
Introduction to Akamon software arquitecture for MPWARIntroduction to Akamon software arquitecture for MPWAR
Introduction to Akamon software arquitecture for MPWAR
 
Integración Continua con Gitlab + Fastlane
Integración Continua con Gitlab + FastlaneIntegración Continua con Gitlab + Fastlane
Integración Continua con Gitlab + Fastlane
 
Virus, el arte de algunos - Alberto García de Dios (/Rooted CON 2011)
Virus, el arte de algunos - Alberto García de Dios (/Rooted CON 2011)Virus, el arte de algunos - Alberto García de Dios (/Rooted CON 2011)
Virus, el arte de algunos - Alberto García de Dios (/Rooted CON 2011)
 
Materiales del curso de Symfony2
Materiales del curso de Symfony2Materiales del curso de Symfony2
Materiales del curso de Symfony2
 
Desde el DVR hasta la cocina
Desde el DVR hasta la cocinaDesde el DVR hasta la cocina
Desde el DVR hasta la cocina
 
Desmitificando SNMP Parte-II
Desmitificando SNMP Parte-IIDesmitificando SNMP Parte-II
Desmitificando SNMP Parte-II
 

RabbitMQ y Symfony

  • 2. Agenda • Introducción a RabbitMQ • RabbitMQ y Symfony • Rabbit en la vida real • Problemas
  • 3. Quien Soy • CTO en chicplace.com • Apasionado de la Web • 8 años en PHP • Whovian y Aerotrastornado
  • 6.
  • 7. ¿Que es RabbitMQ? • Sistema de mensajería • Implementa AMQP • Robusto • Facil de Usar
  • 8. ¿Que he de saber?
  • 9. Mensajes • Body • Body es lo que nosotros decidamos (json/serialize/ binario/txt…) • Header: • Info para el broker • Info para la aplicación
  • 10. Mensajes • Body • Body es lo que nosotros decidamos (json/serialize/ binario/txt…) • Header: • Info para el broker • Info para la aplicación Header Content type Content Encoding Routing key Delivery Mode Message Priority Message publishing timestamp Expiration period App Id Body { "id": 0, "guid": "2cbe2352-6d0e-430b-8faf-122eea44ebf3", "isActive": false, "balance": "$3,243.34", "picture": "http://placehold.it/ 32x32", "age": 25, "eyeColor": "blue", "name": "Lawanda Serrano", "gender": "female", "company": "ELEMANTRA", "email": "lawandaserrano@elemantra.com", "phone": "+1 (827) 534-2331” }
  • 11. Colas • Mensajes esperan a ser consumidos • FIFO • Persistente • Exclusiva • Autoborrado • Round Robin
  • 12. Exchanges • Donde se envían mensajes • Enrutar • Tipos: • Direct • Fanout • Topic • Autoborrado
  • 13. Direct Exchange • Una cola C se subscribe a un exchange con la clave X • Nuevo mensaje con la clave Y • Si X = Y enrutar a cola C
  • 14. Fanout Exchange • El exchange enrutará el mensaje a todas las colas subscritas
  • 15. Topic Exchange • Un mensaje es enrulado a una o varias colas dependiendo de un match con un patrón. https://access.redhat.com/site/documentation/en-US/Red_Hat_Enterprise_MRG/1.1/html/Messaging_User_Guide/chap-Messaging_User_Guide- Exchanges.html
  • 16. Persistencia • ¿Que pasa cuando palma? • Podemos guardar en disco la estructura • Podemos guardar en disco los mensajes • Si guardamos los mensajes debemos guardar la estructura
  • 30. RabbitMQ y Symfony • RabbitMQBundle (https://github.com/videlalvaro/rabbitmqbundle)
  • 31. RabbitMQ y Symfony • RabbitMQBundle (https://github.com/videlalvaro/rabbitmqbundle) • Basado en PhpAmqpLib
  • 32. RabbitMQ y Symfony • RabbitMQBundle (https://github.com/videlalvaro/rabbitmqbundle) • Basado en PhpAmqpLib • Creación de Consumidores/Productores sencilla.
  • 33. RabbitMQ y Symfony • RabbitMQBundle (https://github.com/videlalvaro/rabbitmqbundle) • Basado en PhpAmqpLib • Creación de Consumidores/Productores sencilla. • Configuración de rabbit sencilla.
  • 34. RabbitMQ y Symfony • RabbitMQBundle (https://github.com/videlalvaro/rabbitmqbundle) • Basado en PhpAmqpLib • Creación de Consumidores/Productores sencilla. • Configuración de rabbit sencilla. • No excesivamente estable. Nuevas funcionalidades constantes
  • 35. RabbitMQ y Symfony • RabbitMQBundle (https://github.com/videlalvaro/rabbitmqbundle) • Basado en PhpAmqpLib • Creación de Consumidores/Productores sencilla. • Configuración de rabbit sencilla. • No excesivamente estable. Nuevas funcionalidades constantes • PhpAmqpLib (https://github.com/videlalvaro/php-amqplib)
  • 36. RabbitMQ y Symfony • RabbitMQBundle (https://github.com/videlalvaro/rabbitmqbundle) • Basado en PhpAmqpLib • Creación de Consumidores/Productores sencilla. • Configuración de rabbit sencilla. • No excesivamente estable. Nuevas funcionalidades constantes • PhpAmqpLib (https://github.com/videlalvaro/php-amqplib) • La libreria de referencia.
  • 37. RabbitMQ y Symfony • RabbitMQBundle (https://github.com/videlalvaro/rabbitmqbundle) • Basado en PhpAmqpLib • Creación de Consumidores/Productores sencilla. • Configuración de rabbit sencilla. • No excesivamente estable. Nuevas funcionalidades constantes • PhpAmqpLib (https://github.com/videlalvaro/php-amqplib) • La libreria de referencia. • No te da muchas facilidades
  • 38. RabbitMQ y Symfony composer require oldsound/rabbitmq-bundle:1.3.* Instalación <?php
 public function registerBundles()
 {
 $bundles = array(
 new OldSoundRabbitMqBundleOldSoundRabbitMqBundle(),
 );
 
 return $bundles;
 }
  • 39. old_sound_rabbit_mq: connections: default: host: 'localhost' port: 5672 user: 'guest' password: 'guest' vhost: '/' lazy: true producers: make_thumbnail: connection: default exchange_options: name: 'make-thumbnail-exchange' type: direct durable: true auto_delete: false consumers: make_thumbnail: connection: default exchange_options: name: 'make-thumbnail-exchange' type: direct durable: true auto_delete: false queue_options: {name: 'make-thumbnail-queue',durable: true} callback: solilokiam.rabbitmq.make_thumbnail_consumer RabbitMQ y Symfony Configuración
  • 40. old_sound_rabbit_mq: connections: default: host: 'localhost' port: 5672 user: 'guest' password: 'guest' vhost: '/' lazy: true producers: make_thumbnail: connection: default exchange_options: name: type: direct durable: true auto_delete: false consumers: make_thumbnail: connection: default exchange_options: name: type: direct durable: true auto_delete: false queue_options: { callback: solilokiam.rabbitmq.make_thumbnail_consumer RabbitMQ y Symfony Configuración old_sound_rabbit_mq:! connections:! default:! host: 'localhost'! port: 5672! user: 'guest'! password: 'guest'! vhost: '/'! lazy: true
  • 41. old_sound_rabbit_mq: connections: default: host: 'localhost' port: 5672 user: 'guest' password: 'guest' vhost: '/' lazy: true producers: make_thumbnail: connection: default exchange_options: name: type: direct durable: true auto_delete: false consumers: make_thumbnail: connection: default exchange_options: name: type: direct durable: true auto_delete: false queue_options: { callback: solilokiam.rabbitmq.make_thumbnail_consumer RabbitMQ y Symfony Configuración producers: make_thumbnail: connection: default exchange_options: name: 'make-thumbnail-exchange' type: direct durable: true auto_delete: false
  • 42. old_sound_rabbit_mq: connections: default: host: 'localhost' port: 5672 user: 'guest' password: 'guest' vhost: '/' lazy: true producers: make_thumbnail: connection: default exchange_options: name: type: direct durable: true auto_delete: false consumers: make_thumbnail: connection: default exchange_options: name: type: direct durable: true auto_delete: false queue_options: { callback: solilokiam.rabbitmq.make_thumbnail_consumer RabbitMQ y Symfony Configuración consumers: make_thumbnail: connection: default exchange_options: name: 'make-thumbnail-exchange' type: direct durable: true auto_delete: false queue_options: {name: 'make-thumbnail-queue',durable: true} callback: solilokiam.rabbitmq.make_thumbnail_consumer
  • 43. RabbitMQ y Symfony protected function execute(InputInterface $input, OutputInterface $output) { $width = $input->getOption('width')?$input->getOption('width'):300; $height = $input->getOption('height')?$input->getOption('height'):300; ! $finder = new Finder(); $finder ->files() ->name('*.jpg') ->name('*.png') ->name('*.gif') ->in($input->getArgument('origin')); ! foreach($finder as $file) { $messageArray = array( 'original_image_path' => $file->getRealPath(), 'destination_image_path' => $input->getArgument('destination').'/'.$file->getFileName(), 'width' => $width, 'height' => $height ); ! $this->getContainer()->get('old_sound_rabbit_mq.make_thumbnail_producer') ->setContentType('application/json') ->setDeliveryMode(2) ->publish(json_encode($messageArray)); } }
  • 47. RabbitMQ y Symfony Consumidor class MakeThumbnailConsumer implements ConsumerInterface { public function execute(AMQPMessage $msg) { $data = json_decode($msg->body); $imagine = new Imagine(); try { $imagine->open($data['original_image_path']) ->resize(new Box($data['width'],$data['height'])) ->save($data['destination_image_path']); } catch(Exception $e) { return false; } return true; } ! }
  • 48. RabbitMQ y Symfony app/console rabbitmq:consumer make_thumbnail app/console rabbitmq:consumer make_thumbnail -m 10 app/console rabbitmq:consumer make_thumbnail -l 256 app/console rabbitmq:consumer make_thumbnail -w app/console rabbitmq:purge --no-confirmation make_thumbnail
  • 49. ¿Para que sirve RabbitMQ? • Procesos en batch. • Desacoplar. • Eventos asíncronos • Logs
  • 50. Problemas de la vida real
  • 51. Velocidad • Los productores producen a más velocidad de la que los consumidores son capaces de consumir. • Las colas se llenan • Optimiza el consumidor• Arranca más consumidores Problema Solución
  • 52. Diferencias de Velocidad Problema • Sobre la misma cola un consumidor procesa más mensajes que el otro. • Un consumidor acaba ocioso y el otro tiene mensajes pendientes
  • 54. Diferencias de Velocidad Causa • Algoritmo de round robin de las colas. http://www.cloudamqp.com/
  • 55. Diferencias de Velocidad Causa • Algoritmo de round robin de las colas. Mensaje1 Mensaje2 Mensaje3 Mensaje4 Mensaje5 Mensaje6 Productor http://www.cloudamqp.com/
  • 56. Diferencias de Velocidad Causa • Algoritmo de round robin de las colas. Mensaje1 Mensaje2 Mensaje3 Mensaje4 Mensaje5 Mensaje6 Productor http://www.cloudamqp.com/
  • 57. Diferencias de Velocidad Causa • Algoritmo de round robin de las colas. Mensaje1 Mensaje2 Mensaje3 Mensaje4 Mensaje5 Mensaje6 Productor http://www.cloudamqp.com/
  • 58. Diferencias de Velocidad Causa • Algoritmo de round robin de las colas. Mensaje1 Mensaje2 Mensaje3 Mensaje4 Mensaje5 Mensaje6 Productor http://www.cloudamqp.com/
  • 59. Diferencias de Velocidad Causa • Algoritmo de round robin de las colas. Mensaje1 Mensaje2 Mensaje3 Mensaje4 Mensaje5 Mensaje6 Productor Mensaje1 Mensaje3 Mensaje5 Consumidor 1 Mensaje2 Mensaje4 Mensaje6 Consumidor 2 http://www.cloudamqp.com/
  • 61. Diferencias de Velocidad Solución • channel.basic_qos(prefetch_count=1)
  • 62. Diferencias de Velocidad Solución • channel.basic_qos(prefetch_count=1) consumers: make_thumbnail: connection: default exchange_options: name: 'make-thumbnail-exchange' type: direct durable: true auto_delete: false queue_options: {name: 'make-thumbnail-queue',durable: true} callback: solilokiam.rabbitmq.make_thumbnail_consumer qos_options: {prefetch_size=0, prefetch_count: 1, global: false}
  • 63. Pierdo la conexión Problema • RabbitMQ cierra la conexión TCP cada x minutos. • Mi consumidor se queda colgado
  • 64. Pierdo la conexión • Hacer que el consumer muera al cabo de un tiempo de inactividad. consumers: make_thumbnail: connection: default exchange_options: name: 'make-thumbnail-exchange' type: direct durable: true auto_delete: false queue_options: {name: 'make-thumbnail-queue',durable: true} callback: solilokiam.rabbitmq.make_thumbnail_consumer idle_timeout: 60
  • 65. Pierdo la conexión Solución • Hacer que el consumer muera al cabo de un tiempo de inactividad. consumers: make_thumbnail: connection: default exchange_options: name: 'make-thumbnail-exchange' type: direct durable: true auto_delete: false queue_options: {name: 'make-thumbnail-queue',durable: true} callback: solilokiam.rabbitmq.make_thumbnail_consumer idle_timeout: 60
  • 66. Problemas de comunicación Problema • El formato de mensajes producidos no es entendido por los consumidores. • El formato de los mensajes cambia.
  • 69. Problemas de comunicación Solución • Documentación/Comunicación/Normas • Introducir un traductor de mensajes
  • 70. public function execute(AMQPMessage $msg) { try { $makeThumbnailMsg = $this->translator($msg); $imagine = new Imagine(); $imagine->open($makeThumbnailMsg->getOriginalImagePath()) ->resize(new Box($makeThumbnailMsg->getWidth(),$makeThumbnailMsg->getHeight())) ->save($makeThumbnailMsg->getDestinationImagePath()); } catch(Exception $e) { return false; } ! return true; } Problemas de comunicación
  • 71. Problemas de comunicación class MakeThumbnailTranslator implements TranslatorInterface { public function translateMessage($message) { $data = json_decode($message->body,true); ! if(json_last_error() !== JSON_ERROR_NONE) { throw new Exception('WrongMessage'); } ! $makeThumbnailMessage = new MakeThumbnailMessage(); $makeThumbnailMessage->setOriginalImagePath($data['original_image_path']); $makeThumbnailMessage->setDestinationImagePath($data['destination_image_path']); $makeThumbnailMessage->setWidth($data['width']); $makeThumbnailMessage->setHeight($data['height']); ! return $makeThumbnailMessage; } ! }
  • 72. La importancia del orden Problema • Los mensajes han de ser consumidos en el mismo orden que se han publicado. • Quiero tener mas de un consumer para dar velocidad.
  • 73. La importancia del orden Solución • Sección 4.7 protocolo AMQP: […]Specifically, contents flowing through a single path within the server will remain ordered For contents of a given priority flowing through a single path, we define a content processing path as consisting of one incoming channel, one exchange, one queue, and one outgoing channel.
  • 74. La importancia del orden Solución Un consumer y punto
  • 75. Organización Problema • Múltiples tipos de mensaje. • Múltiples significados. • Muchos consumers vs. Un consumer • Muchos Exchanges vs. Un exchange
  • 76. Organización Solución • Organizar los exchanges por afinidad. • Una cola por exchange (direct o fanout) • Todos los mensajes al mismo consumer • Filtramos por type public function execute(AMQPMessage $message) { if (!array_key_exists($message->get('type'), $this->workers)) { return false; } ! return $this->workers[$message->get('type')]->doWork($message->body); }
  • 77. Organización Solución • Organizar los exchanges por afinidad. • Utilizar el routing de RabbitMQ • Un consumer por tipo de mensaje • Una cola por tipo de mensaje
  • 78. multiple_consumers: make_thumbnail: connection: default exchange_options: name: 'make-thumbnail-exchange' type: direct durable: true auto_delete: false queues: make_thumbnail_video: name: make-thumbnail-video callback: solilokiam.rabbitmq.make_thumbnail_video routing_keys: - video make_thumbnail_picture: name: make-thumbnail-picture callback: solilokiam.rabbitmq.make_thumbnail_picture routing_keys: - picture make_thumbnail_log: name: make-thumbnail-log callback: solilokiam.rabbitmq.make_thumbnail_log Organización Solución
  • 79. multiple_consumers: make_thumbnail: connection: default exchange_options: name: 'make-thumbnail-exchange' type: direct durable: true auto_delete: false queues: make_thumbnail_video: name: make-thumbnail-video callback: solilokiam.rabbitmq.make_thumbnail_video routing_keys: - video make_thumbnail_picture: name: make-thumbnail-picture callback: solilokiam.rabbitmq.make_thumbnail_picture routing_keys: - picture make_thumbnail_log: name: make-thumbnail-log callback: solilokiam.rabbitmq.make_thumbnail_log Organización Solución composer require oldsound/rabbitmq-bundle:dev-master app/console rabbitmq:multiple-consumer make_thumbnail
  • 80. ¿Donde esta la respuesta? Problema • Necesito una respuesta a los mensajes que lanzo. • Quiero poder paralizar las llamadas. • Lo quiero hacer con RabbitMQ.
  • 81. ¿Donde esta la respuesta? Solución rpc_clients: string_reverser: connection: default rpc_servers: string_reverse: connection: default callback: solilokiam.rabbitmq.string_reverser qos_options: {prefetch_size: 0, prefetch_count: 1, global: false}
  • 82. class StringReverser implements ConsumerInterface { protected $translator; ! function __construct(TranslatorInterface $translator) { $this->translator = $translator; } ! public function execute(AMQPMessage $msg) { $stringReverseMessage = $this->translator->translateMessage($msg); ! return strrev($stringReverseMessage->getString()); } ! } ¿Donde esta la respuesta?
  • 83. class StringReverser implements ConsumerInterface { protected $translator; ! function __construct(TranslatorInterface $translator) { $this->translator = $translator; } ! public function execute(AMQPMessage $msg) { $stringReverseMessage = $this->translator->translateMessage($msg); ! return strrev($stringReverseMessage->getString()); } ! } ¿Donde esta la respuesta? app/console rabbit:rpc-server string_reverse
  • 84. ¿Donde esta la respuesta? protected function execute(InputInterface $input, OutputInterface $output) { $reversableString = $input->getArgument('reversable_string'); ! $message_array = array( 'string' => $reversableString ); ! $requestIdentifier = microtime(); ! $client = $this->getContainer()->get('old_sound_rabbit_mq.string_reverser_rpc'); $client->addRequest(json_encode($message_array),'string_reverse',$requestIdentifier); ! $replies=$client->getReplies(); ! $output->writeln($replies); }
  • 85. ¿Donde esta la respuesta? protected function execute(InputInterface $input, OutputInterface $output) { $reversableString = $input->getArgument('reversable_string'); ! $message_array = array( 'string' => $reversableString ); ! $client = $this->getContainer()->get('old_sound_rabbit_mq.string_reverser_rpc'); ! $requestIdentifier = microtime(); ! $client->addRequest(json_encode($message_array),'string_reverse',$requestIdentifier); ! $requestIdentifier2 = microtime(); ! $client->addRequest(json_encode($message_array),'string_capitalize',$requestIdentifier2); ! $replies=$client->getReplies(); ! $output->writeln($replies[$requestIdentifier]); $output->writeln($replies[$requestIdentifier2]); }
  • 87. Vamos a viajar Problema • Nuestra aplicación esta repartida por varias Regiones • Queremos buena latencia. • Queremos que los mensajes se propaguen.
  • 88. Vamos a viajar Solución • Federation https://www.rabbitmq.com/federation.html
  • 91. Vamos a viajar Solución • Shovel • Se conecta a una cola en el broker de origen • Consume el mensaje • Publica el mensaje al broker de destino
  • 92. [{rabbitmq_shovel, [{shovels, [{MyShovels1, [{sources, [{broker,"amqp://guest:guest@Machine01/MyVHost"}]}, {destinations, [{broker, "amqp://guest:guest@Machine02/MyVHost"}]}, {queue, <<"MySourceQueue1">>}, {ack_mode, on_confirm}, {publish_properties, [{delivery_mode, 2}]}, {publish_fields, [{exchange, <<"MyDestExchange">>}, {routing_key, <<>>}]}, {reconnect_delay, 5} ]} ] }] }] Vamos a viajar