Fundamentos de MQTT

MQTT vs NATS: cómo elegir un sistema de mensajería para IoT

MQTT y NATS son sistemas publish/subscribe ligeros, pero se dirigen a clientes distintos. Esta comparativa cubre el soporte de dispositivos, las garantías de entrega, la persistencia y el ecosistema para que sepas dónde encaja cada uno.

Diagrama de microcontroladores conectados a un broker MQTT junto a servicios backend en un clúster NATS, comparando MQTT vs NATS
Pruébalo en tu propio broker MQTTConsigue un broker MQTT privado y gestionado con el plan Free y empieza con ejemplos de código listos para usar.
Pruébalo gratis Ejemplos de código Sin tarjeta

La comparación MQTT vs NATS surge cuando un equipo aprecia la sencillez de NATS para sus microservicios y se pregunta si también podría servir para sus dispositivos. Ambos son sistemas publish/subscribe ligeros con suscripciones por comodines y baja latencia, pero fueron moldeados por clientes muy distintos. Esta guía compara el soporte de dispositivos, las garantías de entrega, la persistencia y el ecosistema, y explica dónde encaja un broker MQTT gestionado junto a NATS.

Dos sistemas pub/sub ligeros

MQTT es un protocolo estándar abierto de OASIS. Cualquier cliente conforme puede hablar con cualquier broker conforme, y existen muchas implementaciones de ambos. Se creó para la telemetría de dispositivos con recursos limitados sobre redes poco fiables, y por eso tiene funciones como Last Will, retained messages y sesiones persistentes.

NATS es un sistema y protocolo de mensajería open source del ecosistema de la CNCF, con una implementación de servidor principal. Se creó para la comunicación nativa de la nube entre servicios: petición/respuesta rápida, difusión y distribución de trabajo con balanceo de carga dentro de un centro de datos y entre varios. NATS core es deliberadamente fire-and-forget; JetStream, integrado en el servidor NATS, añade persistencia, reproducción y garantías de entrega más fuertes.

Los dos son buenos en aquello para lo que se diseñaron. La cuestión es qué clientes vas a conectar.

MQTT vs NATS de un vistazo

Aspecto MQTT NATS
Naturaleza Protocolo estándar de OASIS, muchos brokers Sistema open source, un servidor principal
Direccionamiento Topics con niveles /, comodines + y # Subjects con tokens ., comodines * y >
Entrega (core) QoS 0, 1, 2 Como máximo una vez en NATS core
Persistencia Último valor retenido, colas de sesión Streams de JetStream con reproducción y retención
Distribución de trabajo Suscripciones compartidas (MQTT 5) Queue groups
Petición/respuesta Response topic y correlation data (MQTT 5) Integrada con subjects de inbox
Presencia Keep alive y Last Will Eventos de conexión vía system account, sin Last Will
Último valor conocido Retained messages Último mensaje por subject en JetStream o almacén KV
Librerías para dispositivos Opciones maduras para ESP32, Arduino, C embebido, RTOS Centradas en lenguajes de servidor; pocas opciones para microcontroladores
Acceso desde navegador MQTT sobre WebSocket NATS sobre WebSocket
Ecosistema industrial Sparkplug B, Unified Namespace, soporte en PLC y gateways Limitado
Entorno típico Dispositivos, gateways, HMI, dashboards Microservicios, backends edge-to-cloud, planos de control

El soporte de dispositivos es el factor decisivo

En IoT, la diferencia más práctica es la disponibilidad de clientes. Hay clientes MQTT para prácticamente cualquier plataforma que toque un ingeniero de dispositivos: librerías para ESP32 y Arduino como PubSubClient, librerías en C embebido para entornos RTOS, módulos celulares con MQTT en el firmware del módem, PLC y gateways industriales con MQTT integrado, y software SCADA e historiadores que hablan Sparkplug B. Los sensores y gateways comerciales suelen incluir MQTT como opción de configuración.

Los clientes de NATS son excelentes para Go, Rust, Java, .NET, JavaScript, Python y C en hardware de clase Linux. Una Raspberry Pi o un PC industrial pueden ejecutarlos sin problemas. En microcontroladores y en firmware de fabricantes, el soporte de NATS es raro. Si necesitas que un dispositivo comercial envíe datos sin escribir firmware, casi con toda seguridad hablará MQTT, no NATS.

Garantías de entrega y persistencia

MQTT incorpora garantías de entrega en cada mensaje. Un dispositivo puede publicar una alarma con QoS 1 y una lectura de vibración de alta frecuencia con QoS 0 por la misma conexión. Las sesiones persistentes retienen los mensajes QoS 1 y 2 para un suscriptor que se desconecta, y los retained messages guardan el último valor de cada topic para que un dashboard que se abre más tarde vea el estado actual de inmediato. Para más detalles, consulta los niveles de QoS de MQTT explicados y los retained messages de MQTT.

NATS core entrega a quien esté conectado en ese momento y nada más. Es rápido y sencillo, y es el modelo adecuado para muchas llamadas entre servicios. Cuando necesitas durabilidad, JetStream almacena los mensajes en streams con políticas de retención, permite a los consumidores confirmar y reproducir, y puede deduplicar por ID de mensaje. JetStream es más capaz que las sesiones MQTT en cuanto a historial y reproducción, pero es un conjunto aparte de conceptos (streams, consumidores, políticas de confirmación) que alguien tiene que diseñar y operar.

Presencia y estado del dispositivo

Los sistemas IoT necesitan responder constantemente a la pregunta "¿está este dispositivo en línea y cuál fue su última lectura?". MQTT responde a ambas de forma nativa. Un dispositivo configura un Last Will como offline en site1/pump7/status con el flag retain, publica online tras conectarse, y el broker publica el will si la conexión se cae de forma abrupta. Consulta la guía de MQTT Last Will and Testament para ver el patrón completo.

En NATS normalmente construirías la presencia con heartbeats de cada dispositivo, u observarías los eventos de conexión desde la system account del servidor, y guardarías los últimos valores en un bucket key-value de JetStream. Funciona, pero lo estás ensamblando en lugar de configurarlo.

Subjects frente a topics

Los modelos de nombres son lo bastante parecidos como para traducirse. Un topic MQTT factory1/line2/cnc1/temperature se corresponde de forma natural con un subject NATS factory1.line2.cnc1.temperature. El + de MQTT coincide con un nivel como el * de NATS, y el # de MQTT coincide con el resto como el > de NATS. El servidor NATS incluso ofrece una interfaz MQTT que mapea topics a subjects de esta forma y puede aceptar clientes MQTT 3.1.1, lo que resulta útil cuando NATS ya es la columna vertebral. No admite las funciones de MQTT 5, así que contrasta la documentación de NATS con las funciones de las que dependen tus dispositivos.

Una arquitectura híbrida práctica

Muchos equipos usan ambos, cada uno en la capa que le corresponde:

  1. Los dispositivos, los gateways de PLC y las HMI se conectan a un broker MQTT por TLS.
  2. Un servicio bridge se suscribe a los topics de dispositivos y los republica en subjects NATS para los microservicios del backend.
  3. Internamente, los servicios usan petición/respuesta y queue groups de NATS, y JetStream cuando necesitan streams duraderos.
  4. Los comandos vuelven por el bridge y se publican en el topic de comandos MQTT del dispositivo.

Un bridge unidireccional mínimo en Go tiene este aspecto, usando el cliente Go de Eclipse Paho y el cliente oficial de NATS.

package main

import (
	"crypto/tls"
	"log"
	"strings"

	mqtt "github.com/eclipse/paho.mqtt.golang"
	"github.com/nats-io/nats.go"
)

func main() {
	nc, err := nats.Connect(nats.DefaultURL)
	if err != nil {
		log.Fatal(err)
	}
	defer nc.Drain()

	opts := mqtt.NewClientOptions().
		AddBroker("tls://broker.connectmq.com:8883").
		SetClientID("YOUR_CLIENT_ID").
		SetUsername("YOUR_USERNAME").
		SetPassword("YOUR_PASSWORD").
		SetTLSConfig(&tls.Config{MinVersion: tls.VersionTLS12}).
		SetAutoReconnect(true)

	opts.SetOnConnectHandler(func(c mqtt.Client) {
		// Suscríbete en el handler de conexión para que se restaure tras las reconexiones
		c.Subscribe("factory1/+/+/telemetry", 1, func(_ mqtt.Client, m mqtt.Message) {
			subject := strings.ReplaceAll(m.Topic(), "/", ".")
			if err := nc.Publish(subject, m.Payload()); err != nil {
				log.Printf("nats publish failed: %v", err)
			}
		})
	})

	client := mqtt.NewClient(opts)
	if token := client.Connect(); token.Wait() && token.Error() != nil {
		log.Fatal(token.Error())
	}
	log.Println("bridging MQTT to NATS")
	select {}
}

El cliente Go de paho usa MQTT 3.1.1, que ConnectMQ acepta junto con MQTT 5. Para probarlo sin credenciales, usa tcp://broker.connectmq.com:1883, cualquier client ID único y un prefijo de topic como connectmq/demo/<random-id>/ en el servidor MQTT público gratuito. Ten cuidado con los caracteres que son válidos en los topics MQTT pero especiales en los subjects NATS, como . o los espacios, y sanéalos en el bridge.

Cuándo elegir cada uno

Elige MQTT cuando tus clientes sean dispositivos, gateways, PLC o hardware de terceros, cuando la conectividad sea poco fiable o cuando necesites presencia, estado retenido y convenciones industriales como Sparkplug B y un Unified Namespace.

Elige NATS cuando tus clientes sean servicios que escribes tú, ejecutándose en redes fiables, y quieras petición/respuesta rápida, queue groups y persistencia opcional con JetStream con una infraestructura mínima.

Elige ambos cuando tengas una flota de dispositivos y un backend de microservicios que ya se haya estandarizado en NATS.

Para la capa de dispositivos, un broker MQTT gestionado elimina el trabajo de operar y asegurar un servicio expuesto a internet. ConnectMQ ofrece MQTT 3.1.1 y 5.0, TLS, suscripciones compartidas en el plan Serverless (Paid), cuotas por plan y aislamiento multi-tenant, sin un bridge a NATS integrado, de modo que el bridge sigue siendo tu propio servicio pequeño, como el que se muestra arriba. Si también estás comparando otros backends, consulta MQTT vs Kafka, y para los fundamentos, el tutorial de MQTT.

Empieza con ConnectMQ

Dale a tus dispositivos un endpoint MQTT estándar y bien soportado, y reserva NATS para tus servicios. Crea un broker Serverless gratuito en app.connectmq.com, sin tarjeta de crédito, conecta un dispositivo y tu bridge, y observa ambos lados en el explorador de topics en vivo.

Preguntas frecuentes

¿Es NATS más rápido que MQTT?

Ambos tienen baja latencia, y la velocidad real depende más del servidor, la red y la configuración de entrega que del protocolo. Elige en función de los clientes y las funciones, no de la velocidad bruta.

¿Pueden los dispositivos IoT conectarse directamente a NATS?

Los dispositivos de clase Linux pueden usar clientes NATS. Los microcontroladores y los sensores comerciales rara vez admiten NATS, por eso MQTT domina en la capa de dispositivos.

¿Admite NATS clientes MQTT?

El servidor NATS ofrece una interfaz MQTT 3.1.1 respaldada por JetStream. No cubre las funciones de MQTT 5, así que un broker MQTT dedicado suele encajar mejor con flotas grandes y heterogéneas.

¿Cuál es el equivalente en NATS de un retained message de MQTT?

Los equivalentes más cercanos son un stream de JetStream configurado para guardar el último mensaje por subject, o un bucket key-value de JetStream. Ambos deben configurarse explícitamente.

Artículos relacionados

¿Quién inventó MQTT? La historia, de los oleoductos al IoT

MQTT lo inventaron en 1999 Andy Stanford-Clark, de IBM, y Arlen Nipper, de Arcom, para monitorizar oleoductos vía satélite. Sigue su camino hacia el open source, OASIS, ISO y los brokers MQTT gestionados en la nube de hoy.

8 min de lectura

Por qué tu cliente MQTT se desconecta constantemente (y cómo solucionarlo)

Los bucles de reconexión son uno de los problemas más habituales de MQTT. Conoce las cinco causas típicas, desde los client ID duplicados hasta los timeouts de keep alive y los paquetes demasiado grandes, y sigue un flujo de diagnóstico que localiza la tuya.

9 min de lectura

Todos los artículos →

Tu broker MQTT privado, a unos pocos clics

Crea una cuenta, obtén las credenciales de tu broker y conecta tu primer dispositivo, sin servidores que instalar, parchear ni escalar.