La alta disponibilidad de un broker MQTT consiste en que los dispositivos y las aplicaciones sigan comunicándose cuando falla una parte del sistema, y depende tanto de tus clientes como del broker. Este artículo explica los conceptos clave, qué ocurre realmente con las sesiones y los mensajes durante un failover, cómo diseñar clientes que se recuperen limpiamente y qué preguntas hacer a cualquier proveedor, ConnectMQ incluido, antes de confiar en él.
Qué significa alta disponibilidad en MQTT
En términos generales de infraestructura, alta disponibilidad significa diseñar un sistema de modo que el fallo de un componente no deje todo el servicio caído durante mucho tiempo. En un broker MQTT, eso se desglosa en tres preguntas distintas:
- ¿Pueden los clientes reconectarse rápido? Si falla el proceso del broker, la máquina o la ruta de red, ¿cuánto tardan los dispositivos en poder conectarse de nuevo?
- ¿Qué ocurre con el estado de sesión? ¿Se conservan tras el fallo las suscripciones y los mensajes QoS 1 y 2 en cola para clientes desconectados?
- ¿Qué ocurre con los mensajes en tránsito? ¿Los mensajes aceptados pero aún no entregados se pierden, se entregan una vez o se entregan dos veces?
Las respuestas varían según la arquitectura, y un proveedor excelente en la primera puede no prometer nada sobre la tercera. Sé preciso sobre cuál necesitas.
Arquitecturas habituales de alta disponibilidad
| Patrón | Cómo funciona | Qué sobrevive al fallo de un nodo | Contrapartidas |
|---|---|---|---|
| Nodo único con reinicio rápido | Un broker que se reinicia o sustituye automáticamente al fallar | Conectividad tras el reinicio; el estado depende de la persistencia | Sencillo; breve interrupción durante el reinicio |
| Activo-pasivo | Un nodo en espera toma el relevo cuando falla el principal | Conectividad; estado solo si se replica o está en almacenamiento compartido | La capacidad en espera está ociosa |
| Clúster activo-activo | Varios nodos atienden clientes y enrutan mensajes entre ellos | Conectividad; estado si el clúster lo replica | Más complejo; sobrecarga de coordinación entre nodos |
| Brokers particionados | Brokers independientes por planta, inquilino o región | Solo se ve afectada la partición que falla | No hay un único espacio global de topics |
| Failover en el cliente | Los clientes conocen un endpoint principal y uno secundario | Conectividad, si el secundario está sano | El estado no se comparte entre los dos brokers |
Ninguno es el mejor en todos los casos. Muchos sistemas IoT fiables usan un único broker bien operado por partición más clientes resilientes, porque la arquitectura más sencilla es la que tiene menos formas de fallar.
Dónde encaja un broker MQTT gestionado
Conviene ser directos. ConnectMQ no ofrece clustering con replicación de mensajes, y las sesiones y los mensajes en cola no se conservan entre reinicios del broker. Eso significa que debes diseñar los clientes para tolerar un reinicio del broker reconectándose, volviendo a suscribirse y republicando todo lo importante, que de todas formas es una buena práctica con cualquier broker.
Lo que sí ofrece para planificar la disponibilidad es la elección del modelo de despliegue. Un plan Dedicated te da un clúster aislado, de modo que el tráfico de otros inquilinos no puede afectar al tuyo. BYOC ejecuta el broker en tu propia cuenta cloud, gestionado por ConnectMQ, así que reside dentro de la infraestructura, la red y las regiones que ya controlas. Si necesitas un objetivo de disponibilidad concreto, coméntalo con el equipo para un despliegue Dedicated o BYOC en lugar de dar por supuesta una cifra.
Qué ocurre durante un failover
Cuando un broker se reinicia o un cliente se traslada a otro nodo, la secuencia típica es esta:
- La conexión TCP se cae. El cliente lo detecta de inmediato o tras su intervalo de keepalive.
- Los demás suscriptores reciben el mensaje Last Will, si el broker lo procesa antes del fallo, o una actualización de estado más tarde.
- El cliente se reconecta con backoff.
- Si el broker aún tiene la sesión, el CONNACK indica session present y las suscripciones siguen intactas. Si no, el cliente empieza con una sesión limpia y debe volver a suscribirse.
- Los mensajes publicados mientras el cliente estaba desconectado solo se entregan si el broker los conservó; de lo contrario, se han perdido.
La conclusión práctica: nunca des por hecho que el paso 4 indicará session present. Vuelve a suscribirte en cada conexión y conserva en el cliente todo lo que no puedas permitirte perder hasta que se confirme.
Cómo diseñar clientes para alta disponibilidad
Los clientes resilientes convierten un failover del broker de incidente en un simple parpadeo. Los patrones siguientes funcionan con cualquier broker.
Volver a suscribirse en cada conexión
Pon las suscripciones en el callback de conexión, no en el código de arranque, para que se restauren tras cada reconexión independientemente del estado de sesión.
Almacenar localmente hasta la confirmación
Para los datos importantes, mantén una cola local y elimina un elemento solo después de que el broker confirme una publicación QoS 1. Nuestra guía de MQTT store-and-forward cubre los buffers persistentes en pasarelas.
Failover entre endpoints
Si operas más de un broker, por ejemplo dos despliegues independientes en ubicaciones distintas, el cliente puede rotar entre ellos. Aquí tienes un ejemplo mínimo en Python con paho-mqtt 2.x que rota endpoints, se vuelve a suscribir al conectar y mantiene en memoria los mensajes no confirmados.
import json
import random
import threading
import time
import paho.mqtt.client as mqtt
ENDPOINTS = [("broker.connectmq.com", 8883), ("YOUR_SECONDARY_HOST", 8883)]
BASE = "acme/site1/line1/gw-01"
pending = {} # mid -> (topic, payload), se elimina al confirmarse
lock = threading.Lock()
def send(client, topic, payload):
with lock:
info = client.publish(topic, payload, qos=1)
pending[info.mid] = (topic, payload)
def on_connect(client, userdata, flags, reason_code, properties):
if reason_code.is_failure:
print("refused:", reason_code)
return
print("connected; session present:", flags.session_present)
client.subscribe(f"{BASE}/cmd/#", qos=1) # volver a suscribirse siempre
client.publish(f"{BASE}/status", "online", qos=1, retain=True)
with lock:
unacked = list(pending.values())
pending.clear()
for topic, payload in unacked: # reenviar datos no confirmados
send(client, topic, payload)
def on_publish(client, userdata, mid, reason_code, properties):
with lock:
pending.pop(mid, None)
def on_message(client, userdata, msg):
print("command:", msg.topic, msg.payload.decode())
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
client_id="YOUR_CLIENT_ID", protocol=mqtt.MQTTv5)
client.username_pw_set("YOUR_USERNAME", "YOUR_PASSWORD")
client.tls_set()
client.will_set(f"{BASE}/status", "offline", qos=1, retain=True)
client.on_connect = on_connect
client.on_publish = on_publish
client.on_message = on_message
index, delay = 0, 1
while True:
host, port = ENDPOINTS[index % len(ENDPOINTS)]
try:
client.connect(host, port, keepalive=30)
except OSError as exc:
print(f"{host} unreachable: {exc}")
index += 1
time.sleep(delay + random.random()) # backoff con jitter
delay = min(delay * 2, 60)
continue
delay = 1
client.loop_start()
time.sleep(2) # esperar el CONNACK
while client.is_connected():
reading = json.dumps({"ts": int(time.time()), "rpm": 1480})
send(client, f"{BASE}/telemetry", reading)
time.sleep(5)
client.loop_stop()
print(f"lost {host}, trying the next endpoint")
index += 1
En producción persistirías pending en disco y limitarías su tamaño, pero la estructura es la misma. Como QoS 1 permite duplicados, los receptores deben tolerar que un mensaje llegue dos veces tras un failover. Ten en cuenta que cada endpoint necesita credenciales válidas para ese broker.
Hacer los comandos idempotentes
Tras un failover, un comando QoS 1 puede llegar dos veces. Incluye un ID de comando e ignora los duplicados en el dispositivo.
Republicar el estado en lugar de confiar en que el broker lo conserve
Los mensajes retenidos de estado y configuración son útiles, pero si el broker se reinicia sin persistencia hay que volver a publicarlos. Haz que los dispositivos republiquen el estado retenido en cada conexión, como hace el ejemplo.
Preguntas que hacer a cualquier proveedor MQTT
Usa esta lista en evaluaciones y RFPs. Pide las respuestas por escrito y trata las respuestas vagas como un "no".
- ¿Cuál es la topología de despliegue de mi plan: nodo único, activo-pasivo o clúster?
- ¿Se conservan las sesiones y los mensajes en cola tras un reinicio del broker?
- ¿Se replican los mensajes entre nodos antes de confirmarse?
- ¿Cómo se redirige a los clientes tras un fallo: mismo hostname, cambio de DNS o nuevo endpoint?
- ¿Cuál es el tiempo de recuperación típico tras el fallo de un nodo y figura en el contrato?
- ¿Hay un SLA publicado, qué cubre y cuáles son las compensaciones?
- ¿Cómo se realizan el mantenimiento y las actualizaciones, y se desconecta a los clientes?
- ¿Dónde está la página de estado y cómo se comunican los incidentes?
- ¿Puedo ejecutar un despliegue en una segunda ubicación o en mi propia cuenta cloud?
- ¿Qué pasa con mi carga de trabajo si otro inquilino se comporta mal en un plan compartido?
En nuestro propio servicio, la respuesta a las preguntas 2 y 3 es que no se ofrecen persistencia entre reinicios ni replicación de mensajes, y para los términos del SLA debes preguntar directamente al equipo. Nuestro artículo sobre el SLA de un broker MQTT explica cómo interpretar el lenguaje de los SLA, y la checklist de RFP para brokers MQTT incluye una lista de evaluación más extensa.
Patrones prácticos de alta disponibilidad con un broker MQTT gestionado
Combinando los conceptos anteriores, un enfoque realista para la mayoría de los equipos es este:
- Elige un broker MQTT gestionado para que los parches, TLS y los fallos de máquina sean trabajo de otro.
- Usa un despliegue Dedicated si necesitas aislamiento respecto a otros inquilinos.
- Usa BYOC si el broker debe residir en tu propia cuenta cloud junto a tus otros sistemas.
- Particiona por planta o por cliente cuando una caída no deba afectar a todos; la planta de Monterrey y la de Bilbao no tienen por qué compartir broker.
- Construye cada cliente con resuscripción al conectar, buffer local, comandos idempotentes y backoff con jitter.
- Monitoriza el estado de conexión, por ejemplo mediante
$SYS/broker/connection/{clientId}/state, y genera alertas cuando los dispositivos se desconecten.
Para la capacidad junto a la disponibilidad, consulta cómo escalar un broker MQTT, y para el panorama general de alojamiento lee la guía del broker MQTT en la nube.
Planifica la disponibilidad de tu MQTT con ConnectMQ
ConnectMQ es un broker MQTT gestionado con opciones Serverless, Dedicated y BYOC, para que elijas el modelo de despliegue que se ajuste a tus necesidades de disponibilidad. Empieza gratis en app.connectmq.com sin tarjeta de crédito, construye clientes resilientes contra él (la lógica de reconexión también puedes ensayarla en el servidor MQTT público gratuito de broker.connectmq.com, solo para pruebas, nunca con datos de producción) y habla con el equipo cuando necesites un despliegue Dedicated o BYOC.
Preguntas frecuentes
¿Tiene MQTT alta disponibilidad integrada?
No. El protocolo MQTT define sesiones, QoS y Last Will, pero la alta disponibilidad depende de cómo se despliega el broker y de cómo gestionan los clientes las reconexiones.
¿Sobrevivirá mi sesión MQTT a un reinicio del broker?
Solo si el broker persiste las sesiones. Muchos despliegues, incluido el nuestro, no conservan las sesiones entre reinicios, así que los clientes deben volver a suscribirse y republicar el estado importante en cada conexión.
¿Hace falta un clúster para tener un sistema MQTT fiable?
No siempre. Los clientes bien diseñados, los brokers particionados y los despliegues aislados dan a muchos sistemas una gran fiabilidad sin un clúster replicado.
¿Qué debo preguntar a un proveedor sobre la alta disponibilidad de su broker MQTT?
Pregunta por la topología, la persistencia de sesiones, la replicación de mensajes, el comportamiento en failover, las ventanas de mantenimiento y los términos del SLA por escrito. Obtén las respuestas por escrito antes de comprometerte.



