Divide y vencerás: Parte 1

Víctor Arroyo
BigBuy Team
Published in
3 min readDec 22, 2021

Una de las primeras premisas que te inculcan cuando estás estudiando informática es que los problemas son menos problemas si los divides. Cada dos por tres el tema salía a la palestra. Esto llevado a la informática se extrapola a que, cualquier proceso, si quieres que sea escalable y atómico, lo mejor que puedes hacer es dividirlo en pequeños problemas que sean menos pesados.

Para tratar de explicarlo, vamos a poner un ejemplo. Pensemos que tenemos un montón de información que procesar, por ejemplo, un fichero XML. Este fichero estaría formado por un montón de nodos que a su vez contienen otros nodos para dar valor a distintas propiedades. Por ejemplo tengamos una estructura así:

<notes>
<note>
<to>Juan</to>
<from>Jose</from>
<heading>Recordatorio</heading>
<body>Lllámame para quedar el fin de semana</body>
</note>
<note>
<to>Luis</to>
<from>Ana</from>
<heading>Fiesta</heading>
<body>¿Cómo te lo pasaste en la fiesta?</body>
</note>

</notes>

Si quisiéramos procesar la información que tenemos en el XML, en un primer momento optaríamos por leer el documento y nodo a nodo de “note” iríamos ejecutando la lógica que tuviéramos establecida. Este tipo de solución, ya se ve que no es nada escalable porque, ¿qué pasará cuando tengamos 1.000, 100.000 o un 1.000.000 de registros? Pues que nuestro proceso pegará un castañazo, necesitaremos un maquinón para poder ejecutarlo y encima tardará un mundo en finalizar.

Para solucionar esto, vienen en nuestra ayuda los gestores de colas. Estos sistemas introducen el concepto de mensaje, facilitando realizar una separación en los procesos para pasar a ser productores y consumidores.

En el mercado podemos encontrar múltiples soluciones como por ejemplo RabbitMQ, Kafka o Pulsar, cada una con sus particularidades a nivel del patrón de mensajería que utilizan y otras cuestiones relacionadas con la escalabilidad.

En nuestro caso nos decantamos por el uso de RabbitMQ, el cual utiliza el modelo publicador-suscriptor.

Para llevarlo a nuestro ejemplo, nuestro proceso se dividiría en varias subprocesos:

El productor

Este primer proceso ha de encargarse de generar los mensajes. En nuestro caso vamos a suponer que se encargaría de leer la información del fichero XML y nodo a nodo, iría publicando mensajes (uno por nodo) en una cola de nuestro gestor de colas. De esta forma, la información que anteriormente había de procesarse directamente, ahora pasa a estar ordenada y segmentada, lista para ser “releída”.

El bróker

Este gestor se encarga de recibir la información y enrutarla hacia la cola deseada. De esta forma, el sistema almacena los mensajes que recibe del productor para dejarlos a la espera de que el consumidor los solicite.

El consumidor

Esta es la parte del proceso que realiza la lógica que aplicábamos a cada nodo del XML. Ahora, se encargará de aplicarla únicamente sobre una porción del fichero, la cual leeremos desde la interfaz que nos proporciona el bróker (en nuestro caso RabbitMQ). Nuestro proceso leerá un mensaje de la cola. A estas alturas, ya se vislumbra la posibilidad de ejecutar varios procesos consumidores, los que nos proporcionará una escalabilidad mayor y disminuirá los tiempos de ejecución.

Como resultado, entre otros muchos beneficios, disponemos de un sistema que ahora nos permitirá procesar mucha más información, de forma asíncrona, con un control absoluto del ritmo de procesamiento y, añadiendo si es necesario, la posibilidad de ejecutar procesos de forma concurrente.

Bonus 1: Gestión de errores

Como beneficio adicional, esta forma de procesamiento nos va a permitir detectar los posibles errores de forma atómica y aislarlos evitar que el resto del procesamiento de la información se vea afectada. Una de las fórmulas aconsejable, pasa por disponer de una cola separada para llevar los errores

Bonus 2: Integrando RabbitMQ en Symfony

A la hora de integrar este servicio dentro de Symfony, ya disponemos de un bundle que facilita todo el trabajo para integrar la librería nativa de PHP para AMQP

https://github.com/php-amqplib/RabbitMqBundle

Siguiendo la receta que existe en la documentación seremos capaces de configurarla conexión con el servicio dentro de nuestro proyecto en unos sencillos pasos.

--

--