Esta charla pretende enseñar como añadir RabbitMQ a un proyecto Symfony.
Charla realizada en Symfony Barcelona el dia 2 de julio. Podeis encontrar ejemplos de código en https://github.com/solilokiam/rabbitmqexample
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
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;
}
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
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/
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.
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.
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
80. ¿Donde esta la respuesta?
Problema
• Necesito una respuesta a los mensajes que lanzo.
• Quiero poder paralizar las llamadas.
• Lo quiero hacer con RabbitMQ.
87. Vamos a viajar
Problema
• Nuestra aplicación esta repartida por varias Regiones
• Queremos buena latencia.
• Queremos que los mensajes se propaguen.