Universidad Nacional de Luján
Departamento de Ciencias Básicas
Sistemas Distribuidos y Programación Paralela 2026 Dr. David Petrocelli
TP 3 · Parte 1
📑 Índice del documento

Trabajo Práctico Nº 3 — Parte 1

Computación Distribuida (Kubernetes / RabbitMQ)

Fecha de entrega: 05/05/2026 — todos los puntos.


Requisitos, consideraciones y formato de entrega


Contenidos del programa relacionados


Ámbito de ejecución: todos los Hits de esta Parte 1 corren sobre Kubernetes local (Microk8s, k3s o similar). El despliegue en la nube es el alcance de la Parte 2.

Hit #0 — Patrones de Mensajería con RabbitMQ

Antes de comenzar con el procesamiento distribuido de imágenes, es fundamental comprender los patrones de mensajería [HOH03] que van a usar a lo largo de este TP y del TP Integrador. RabbitMQ [RMQ] —que implementa el protocolo AMQP 0-9-1 [AMQP]— va a ser su broker de mensajes, y necesitan entender cómo funciona y qué patrones soporta. La referencia clásica de Tanenbaum & Van Steen [TAN17] cubre los fundamentos teóricos de comunicación asincrónica entre procesos distribuidos.

Implementen los siguientes 4 ejemplos simples utilizando RabbitMQ. Cada ejemplo es un programa funcional independiente con su código en una subcarpeta dedicada del repositorio (TP3/queue/exN/), e incluye los manifiestos de Kubernetes para desplegarlo.

Patrón 1 — Message Queue

Ejemplo 1 — Message Queue (punto a punto)

Un productor envía mensajes a una cola y un solo consumidor los recibe. Cada mensaje es procesado exactamente por un consumidor. Implementen un productor que envíe 10 tareas numeradas y un consumidor que las reciba y las imprima. Después levanten 2 consumidores y observen cómo RabbitMQ distribuye los mensajes entre ambos (round-robin). Documenten el comportamiento observado.

Patrón 2 — Pub/Sub Fan-out

Ejemplo 2 — Event Bus / Pub-Sub (fan-out)

Un productor publica eventos en un exchange de tipo fanout y todos los consumidores suscritos reciben una copia del mensaje. Implementen un publicador que emita eventos de “nuevo bloque minado” y 3 suscriptores que representen nodos de la red que deben recibir la notificación. Verifiquen que los 3 reciben el mismo mensaje.

En la industria, este patrón lo implementan servicios como AWS EventBridge, Google Pub/Sub y Apache Kafka [KREP11] —diseñado originalmente en LinkedIn para procesamiento de logs distribuidos a escala masiva.

Patrón 3 — Dead Letter Queue

Ejemplo 3 — Dead Letter Queue (DLQ)

Configuren una cola principal con un Dead Letter Exchange (DLX) en RabbitMQ. El consumidor debe rechazar (nack) los mensajes que contengan un campo "error": true, y estos deben ser redirigidos automáticamente a la cola de Dead Letters. Implementen un segundo consumidor que lea la DLQ e imprima los mensajes fallidos.

Este patrón es fundamental para no perder mensajes que no pudieron ser procesados. En la industria se usa en SQS + DLQ (AWS) y RabbitMQ DLX.

Patrón 4 — Retry con Exponential Backoff

Ejemplo 4 — Retry con Exponential Backoff

Implementen un consumidor que al recibir un mensaje intente procesarlo, y si falla (simulen un fallo aleatorio con probabilidad del 50%) lo reencole con un delay creciente: 1s, 2s, 4s, 8s (exponential backoff). Después de 4 reintentos fallidos, envíen el mensaje a la DLQ del ejemplo anterior.

Para implementar el delay pueden usar el plugin rabbitmq_delayed_message_exchange o TTL por mensaje con una cola intermedia. Registren en un log el número de intento y el tiempo de espera de cada reintento.

Este patrón es estándar en la industria para manejar fallos transitorios (servicios caídos, timeouts, rate limits).

Ejemplo 5 — Discusión

Documenten en el informe (TP3/queue/ex5/): un diagrama de arquitectura de cada patrón, las diferencias entre ellos y en qué escenarios usarían cada uno. Esta base les va a servir para los Hits siguientes, donde aplicarán estos patrones al procesamiento distribuido de imágenes.

Recordatorio de entrega del Hit #0: cada ejemplo va en su carpeta TP3/queue/exN/ con el código de la aplicación, los manifiestos de Kubernetes y un breve README.md. El Ejemplo 5 incluye solo la documentación comparativa.


Hit #1 — El operador de Sobel (“un equipo”)

El operador de Sobel [SOB68] es una máscara que, aplicada a una imagen, permite detectar (resaltar) bordes. Es una operación matemática que, aplicada a cada píxel y considerando los píxeles vecinos, obtiene un nuevo valor (color) para ese píxel. Aplicando la operación a cada píxel se obtiene una nueva imagen que resalta los bordes.

Objetivo:

Etapa 1 — Centralizado. Desarrollen un proceso centralizado que tome una imagen, aplique la máscara y genere un nuevo archivo con el resultado. Ámbito: una sola laptop / equipo.

Etapa 2 — Distribuido. Desarrollen el mismo proceso de manera distribuida: dividan la imagen en N pedazos y asignen la tarea de aplicar la máscara a N procesos distribuidos (workers). Después unifiquen los resultados. Este es exactamente el patrón Master-Worker (también llamado Granja de Trabajadores) que Foster [FOS95] caracteriza como uno de los esquemas algorítmicos paralelos fundamentales. Ámbito: Docker.

Etapa 3 — Tolerante a fallos. Mejoren la aplicación de la Etapa 2 para que, en caso de que un worker (proceso distribuido al que se le asignó parte de la imagen a procesar) se caiga y no responda, el proceso principal detecte la situación y reasigne el cálculo a otro worker.

Hit #1 — Sobel Distribuido con Workers Docker

Referencias y Bibliografía

Libros y papers fundacionales

Especificaciones y documentación técnica

Herramientas