// Python Dev

RabbitMQ como puente entre el entorno externo y el interno

Publicado el 03.04.2026

Los brokers de colas suelen percibirse como una herramienta dentro de un mismo sistema: desacoplar microservicios, suavizar picos de carga, organizar tareas en segundo plano. Pero hay una aplicación mucho menos obvia: usar el broker como punto de acceso a datos que están físicamente dentro de la organización y no salen al exterior.

En la práctica, cualquier intento de dar acceso externo a datos internos se convierte rápidamente en un proyecto de infraestructura: aprobaciones, seguridad, restricciones de red. Incluso una tarea simple como “obtener el saldo de un cliente” puede atascarse durante semanas y requerir la participación de varios equipos.


Datos dentro, solicitud desde fuera

Situación típica: hay una aplicación externa —un panel de usuario, una app móvil o un servicio de un partner— que necesita obtener datos actualizados desde un sistema interno. Por ejemplo, el saldo de un cliente desde el billing.

Las opciones estándar son todas peores unas que otras. Abrir un puerto hacia fuera —la opción más obvia— es lo primero que descartan los de seguridad, y con razón. Levantar una VPN suena razonable, pero en la práctica es otro proyecto con sus propias aprobaciones, certificados y soporte, y no siempre posible en el lado del sistema externo, especialmente si está en la nube de un tercero. Una IP pública puede simplemente no existir: el proveedor da IP dinámica detrás de NAT, y exponer una conexión desde fuera hacia dentro sin infraestructura adicional es imposible. Para compañías pequeñas y sucursales esto es una situación completamente habitual.

Caso real

En uno de los proyectos había que implementar un bot de Telegram para un proveedor, a través del cual el usuario podía ver su saldo actual. El problema era que el sistema de billing estaba en un contorno cerrado dentro del centro de datos y tenía un API SOAP accesible solo desde dentro de la red. Abrir acceso externo estaba prohibido, implementar una VPN desde el lado del bot era imposible, y el bot corría en la nube. Al final, incluso la simple petición “mostrar saldo” se convertía en una tarea de integración entre sistemas completamente aislados.


Broker afuera como punto de encuentro

La idea es simple pero no obvia: levantar una instancia de RabbitMQ no dentro de la organización, sino afuera —cerca de la aplicación externa, en un servidor de acceso público. Ese broker es simultáneamente accesible tanto por el sistema externo como por el interno —porque el servicio interno inicia la conexión saliente hacia afuera, y las conexiones salientes, a diferencia de las entrantes, casi nunca son bloqueadas por firewalls o NAT.

El esquema queda así: la aplicación externa pone la petición en una cola en el broker. El servicio dentro de la organización escucha esa cola, toma la petición, consulta el billing u otra fuente interna, y pone la respuesta en otra cola. La aplicación externa toma la respuesta.

Los datos salen justo cuando son necesarios, y solo los que se pidieron. El sistema interno permanece cerrado —es él quien decide cuándo y qué entregar.


RPC sobre colas: asincronía sin dolor

La dificultad obvia de este esquema es la asincronía. Cuando hay muchas peticiones, hay que entender qué respuesta corresponde a qué solicitud. Se puede etiquetar cada mensaje manualmente, pero RabbitMQ proporciona un mecanismo listo: RPC sobre colas.

Funciona así: el cliente al enviar la petición indica el nombre de una cola temporal donde espera la respuesta (reply_to) y un correlation_id único. El servicio interno procesa la petición y envía la respuesta no a la cola común, sino directamente a esa cola temporal con el mismo correlation_id. El cliente simplemente espera su respuesta —sin lógica adicional de enrutamiento.

No es necesario implementar esto a mano —RPC sobre RabbitMQ ya lo soportan bibliotecas. Por ejemplo, FastStream proporciona una interfaz declarativa cómoda: el suscriptor a una cola se describe como una función async normal, y la biblioteca se encarga de reply_to y correlation_id. El código queda más compacto y se lee como un servicio habitual, no como trabajo directo con el broker.

Abajo hay un ejemplo mínimo con pika, para entender qué ocurre bajo el capó.

Cliente (sistema externo)

import pika, uuid

connection = pika.BlockingConnection(pika.ConnectionParameters('broker.example.com'))
channel = connection.channel()

# Cola temporal para la respuesta — RabbitMQ la eliminará automáticamente al desconectarse
result = channel.queue_declare(queue='', exclusive=True)
reply_queue = result.method.queue
correlation_id = str(uuid.uuid4())

channel.basic_publish(
    exchange='',
    routing_key='billing.requests',
    properties=pika.BasicProperties(
        reply_to=reply_queue,
        correlation_id=correlation_id,
    ),
    body='{"client_id": 42, "action": "get_balance"}'
)

# Esperamos la respuesta exactamente para nuestra petición
for method, props, body in channel.consume(reply_queue):
    if props.correlation_id == correlation_id:
        print(f"Saldo: {body.decode()}")
        channel.cancel()
        break

Procesador (servicio interno)

import pika, json

connection = pika.BlockingConnection(pika.ConnectionParameters('broker.example.com'))
channel = connection.channel()
channel.queue_declare(queue='billing.requests')

def on_request(ch, method, props, body):
    request = json.loads(body)
    balance = get_balance_from_billing(request['client_id'])  # acceso a la fuente interna

    ch.basic_publish(
        exchange='',
        routing_key=props.reply_to,
        properties=pika.BasicProperties(correlation_id=props.correlation_id),
        body=str(balance)
    )
    ch.basic_ack(delivery_tag=method.delivery_tag)

channel.basic_consume(queue='billing.requests', on_message_callback=on_request)
channel.start_consuming()

Esto convierte la interacción asíncrona en algo casi sincrónico desde el punto de vista del código: envias la petición —esperas— recibes la respuesta. Al mismo tiempo no es necesario almacenar ningún estado adicional.


Qué se consigue

Este esquema resuelve varias problemas de golpe sin infraestructura extra: no hace falta IP pública, no hace falta VPN, no es necesario abrir acceso al contorno interno. Autorización y cifrado se resuelven a nivel de RabbitMQ —TLS y credenciales sustituyen toda la infraestructura de API keys y tokens. Desplegar esto puede hacerse en uno o dos días: dos servicios pequeños y una instancia del broker.

No es una herramienta universal. Pero para tareas donde se necesita dar acceso a datos desde un contorno cerrado bajo demanda —billing, CRM internos, sistemas contables— es una de las opciones más simples y baratas. Para transmisión continua de grandes volúmenes o escenarios con requisitos estrictos de latencia el esquema encaja peor —ahí ya hacen falta otras herramientas.

// Python Dev

Другие статьи Python Dev

Все статьи

// Python Projects

Проекты Python Dev

Все проекты

2026-03-26

Bot de Telegram para bromas de voz

Ampliacion de un bot de Telegram existente: llamadas por SIP y Telegram, grabacion de respuestas y monetizacion mediante Telegram Stars.

// Contact

¿Necesitas ayuda?

Escríbeme y te ayudaré a resolver el problema

Enviar solicitud
Escribir y recibir una respuesta rápida