Introducción a MQTT

Agustin Bassi

Feb 05, 2021 ‧ 35 min estimados ‧ #mqtt #broker #mosquitto #topic

Contenido

Objetivos

Aspectos generales de MQTT

Arquitectura

Detalles de comunicación

Mensajes LWT

Calidad de servicio (QoS)

Autenticación

MQTT sobre WebSockets

Escalabilidad

Tecnologías MQTT

Conclusiones

Bibliografía

Licencia

Objetivos

Lo que vas a ver en este documento son los siguientes temas:

Aspectos generales de MQTT

MQTT (Message Queue Telemetry Transport) es uno de los protocolos más utilizados y difundidos en IoT. Fue ideado por IBM en 1999 como una forma rentable y confiable de conectar  dispositivos de monitoreo utilizados en las industrias del petróleo y el gas con servidores empresariales remotos mediante enlaces satelitales.

Es un protocolo de capa de aplicación, posee una topología de estrella y sus mensajes se transmiten como colas de publicación/suscripción. El nodo central de su topología se llama broker donde conectan los clientes remotos. Los clientes pueden ser por ejemplo dispositivos con sensores y actuadores, así como también centrales de monitoreo, interfaces gráficas, entre otros.

Para que puedas apreciar mejor en la capa en que se encuentra, en la imagen siguiente podés ubicarlo junto con otro stack de tecnologías IoT.

La finalidad de MQTT es minimizar el uso recursos en los dispositivos (CPU, RAM, ROM), ser confiable y ofrecer distintos niveles calidad del servicio. Consume un ancho de banda relativamente bajo y mantiene una conexión continua entre el broker y los clientes.

Generalmente se suele usar este protocolo como nexo entre los dispositivos en campo - generalmente dispositivos asociados a sensores y actuadores - con elementos típicos de software como servidores webs, bases de datos, herramientas de análisis, entre otros. Es la capa que se encarga de hacer llegar un mensaje a un sistema más grande que posteriormente puede almacenarlo, procesarlo y sacar valor. En la siguiente figura podés ver un diagrama de arquitectura típico que utiliza MQTT como nexo.

Entre las principales características de MQTT podemos encontrar las siguientes:

Aunque todavía se suele asociar  a IBM, MQTT fue liberado y actualmente es un protocolo abierto supervisado por la Organización OASIS.

Arquitectura

El protocolo MQTT define al broker como entidad central al que se conectan varios clientes. El broker se encarga de gestionar la red, recibir todos los mensajes de los clientes y redirigirlos hacia los clientes de destino.

Un cliente es cualquier dispositivo que pueda interactuar con el broker para enviar/recibir mensajes. Puede ser un sensor de IoT en campo o una aplicación en un centro de datos que procesa datos provenientes de los sensores. Cualquier cliente puede publicar o suscribirse a topics (temas) para acceder a la información.

Tiene una topología de estrella con el broker como nodo central, y en la siguiente figura podés ver al broker y los clientes que se conectan para enviar/recibir mensajes.

Está orientado a redes de dispositivos pequeños que necesitan la supervisión o el control de un servidor y no está diseñado para la transferencia directa entre dispositivos, todo debe pasar por el broker. Las aplicaciones que usan MQTT por lo general son lentas en el sentido que la definición de “tiempo real” en este caso se mide habitualmente en segundos.

Los mensajes MQTT se organizan por topics y el desarrollador de aplicaciones tiene la flexibilidad de especificar la arquitectura y determinar qué clientes pueden interactuar con qué mensajes.

Pongamos un ejemplo de implementación MQTT entre dispositivos remotos que transmiten mediciones de sensores, una aplicación de monitoreo que analiza los datos de los sensores y una central de control. Los dispositivos publican las lecturas de los sensores en el topic sensor_data y se suscriben al topic config_change. La aplicación de monitoreo guarda los datos del sensor en una base de datos suscribiéndose al topic sensor_data. La central de control que administra el sistema podría ajustar las configuraciones de los sensores, tales como la sensibilidad y la frecuencia de muestreo, publicando tales cambios en el topic config_change.

Detalles de comunicación

La comunicación se basa en la publicación y suscripción a topics. Los clientes que publican crean mensajes en determinados topics y los nodos que deseen recibirlo deben suscribirse a estos topics.

Con suscribirte a un topic podrías hacer una analogía con una suscripción a una lista de correo. Te van a llegar correos siempre y cuando te hayas suscripto, no en otro caso.

La comunicación puede ser de uno a uno o de uno a muchos. Una secuencia de comunicación típica es como la siguiente:

  1. El cliente se conecta al broker brindándole su ID de cliente. Así mismo, puede suscribirse a cualquier topic que le sea relevante.
  2. El cliente publica mensajes en un topic y enviándolos al broker.
  3. El broker analiza el topic y se lo reenvía a todos los clientes disponibles que se suscribieron a tal topic.

Un topic se representa mediante una cadena de texto con una estructura jerárquica. Cada jerarquía se separa con el caracter "/". Un ejemplo de topics podría ser edificio1/planta5/sala1/raspberry2/temperatura o /edificio3/planta0/sala3/arduino4/ruido. De esta forma se pueden crear jerarquías de clientes que publican y reciben datos de manera sencilla. En la siguiente imagen podés ver un ejemplo de la jerarquía de topics.

jerarquia

De esta forma un nodo puede subscribirse a un topic concreto, como por ejemplo  edificio1/planta2/sala0/arduino0/temperatura  o bien a varios topics al mismo tiempo, por ejemplo edificio1/planta2/#. El caracter "#" permite referirse a cualquier topic.

La comunicación está establecida por sesiones y una sesión MQTT se divide en cuatro etapas.

Un cliente comienza creando una conexión TCP/IP con la IP y puerto del broker. Los puertos estándar son el 1883 para la comunicación no cifrada, el 8883 para la comunicación cifrada mediante SSL/TLS y el 9001 para websockets. Al crear la conexión el servidor puede continuar una sesión anterior si el cliente le proporciona un ID existente.

Dentro de MQTT cada mensaje consta de una cabecera fija, una cabecera variable opcional, una payload (carga útil) y un nivel de calidad de servicio (QoS). Además de los protocolos  de comunicación estándar como XML o JSON, MQTT también soporta BLOBS (Binary Large Object) de hasta 256 MB de tamaño. En la siguiente figura podés observar cómo está compuesta una trama.

MQTT tiene 14 tipos de mensajes, aunque en la mayoría de los casos es muy probable que solo uses los mensajes de CONNECT, PING, SUBSCRIBE, UNSUBSCRIBE, PUBLISH, DISCONECT y LWT.

Mensajes LWT

Cuando un cliente se conecta al broker puede definir un topic y un mensaje que se publicará automáticamente si se desconecta de forma inesperada. Cuando el temporizador keep alive del broker detecta que el cliente no ha enviado recientemente un topic o un mensaje PINGREQ (que se usa para mantener activa la conexión) se publica inmediatamente el mensaje LWT especificado por el cliente.

La función LWT se puede utilizar para crear notificaciones en aplicaciones que supervisan la actividad de los clientes.  En la siguiente figura podés ver un diagrama que demuestra cómo ocurre un mensaje LWT.

Calidad de servicio (QoS)

MQTT está diseñado para ser simple y minimizar el ancho de banda, lo que lo convierte en una buena opción para muchos escenarios; aunque esta simplicidad hace que la interpretación de los mensajes dependa completamente del diseñador del sistema. Para mitigar este tipo de inconvenientes se soportan distintos niveles de calidad de servicio.

Estos niveles determinan cómo se entrega cada mensaje y es necesario especificar un QoS para cada topic MQTT. Es importante elegir el valor de QoS adecuado para cada mensaje que está determinado de la siguiente manera.

La regla simple con la QoS es que cuanto mayor sea menor será el rendimiento. MQTT proporciona flexibilidad a los clientes para elegir la calidad de servicio apropiada. En la imagen siguiente podemos ver un diagrama de cómo actúa el parámetro QoS.

Autenticación

En MQTT se puede establecer una comunicación cifrada mediante SSL/TLS. Durante el handshake SSL/TLS el cliente valida el certificado del servidor para autenticarlo. El cliente también puede proporcionar un certificado al broker durante el handshake que el broker puede utilizar para autenticar al cliente. Aunque no forma parte de la especificación se ha convertido en una práctica común que los broker admitan la autenticación con certificados.

En otros casos también se añade al sistema un Authorization Server -un servicio separado del broker- que se encarga de brindar un token de autenticación a los clientes. Al querer conectarse al broker el cliente debe proveer el token y el broker valida el token comunicándose con el Authorization Server. En la figura siguiente podés ver un ejemplo de implementación.

Si bien la autenticación con certificados suele ser la opción más segura, esta opción puede no ser viable en dispositivos IoT con recursos limitados ya que es una opción compleja. Para estos casos donde se requiera una capa de seguridad sin comprometer demasiado los recursos de un dispositivo se puede realizar la comunicación utilizando usuario y contraseña que el cliente envía al broker en la secuencia de conexión. En el diagrama siguiente podés ver una secuencia de comunicación entre un cliente MQTT y un broker de ThingSpeak.

MQTT sobre WebSockets

WebSocket es un protocolo de comunicaciones web que proporciona canales de comunicación continuos sobre una conexión TCP/IP.  Está estrechamente asociado con HTTP ya que utiliza este protocolo para el establecimiento de conexión inicial.

Para comenzar una conexión el cliente y el servidor se conectan utilizando HTTP y luego negocian una actualización de la conexión a WebSockets. Cuando la conexión queda establecida se mantiene un canal de comunicación continuo (socket) entre cliente y servidor a diferencia del modelo request-response empleado en HTTP. En la siguiente imagen podés ver un diagrama de negociación de WebSockets.

MQTT sobre WebSockets permite comunicarse con un broker directamente en un navegador web. Para que esto sea posible es necesario utilizar una biblioteca de JavaScript que realiza esta comunicación del lado del cliente.

Para estos casos la conexión de WebSockets forma un envoltorio sobre MQTT. Cada mensaje MQTT se monta sobre un paquete de WebSockets. El cliente desempaqueta el mensaje del WebSocket y lo procesa como si fuera un paquete MQTT. Podés ver el proceso en esta imagen.

Escalabilidad

En una arquitectura basada en un nodo central como un broker MQTT es fundamental evitar el punto único de fallo. Para mitigar este problema se abordan 2 estrategias principales.

Bridging

En este tipo de estrategia se realiza reenvío de mensajes hacia otro broker MQTT para evitar que estos se puedan perder en un solo broker. En la siguiente imagen podés ver de qué se trata esta técnica.

Clustering

Esta solución permite el escalado dinámico de brokers, es decir agregar o quitar instancias de broker, dependiendo de la carga que se tenga en cada momento. En la siguiente imagen podés ver un diagrama utilizando esta técnica.

Tecnologías MQTT

Hay una gran cantidad de brokers MQTT tanto para correr de manera local como en la nube, gratuitos y pagos. Algunas soluciones proveen brokers únicamente, mientras que otras proveen brokers y clientes.

En este link podés ver una lista de servidores públicos y gratuitos que podés usarlos para pruebas. Es importante que la información que mandes a estos brokers no sea sensible ya que los mensajes estarán públicamente disponibles. También podés encontrar más información en EMQX y en Test Mosquitto.

Si tenés la posibilidad de pagar una suscripción podés usar CloudMQTT que es un broker distribuido globalmente diseñado para mensajería de IoT con dispositivos de baja potencia. Es una buena opción para hacer pruebas de manera rápida aunque es necesario crear una cuenta y abonar por el servicio.

Yendo a una opción libre y gratuita podés instalar Mosquitto que es un broker de código abierto ampliamente utilizado. El broker Mosquitto es parte del grupo de trabajo de Eclipse IoT y se puede instalar fácilmente en la mayoría de los sistemas operativos incluso en una Raspberry Pi. También está disponible mediante un contenedor de Docker.

Respecto a clientes y los lenguajes que podés utilizar para crear aplicaciones con MQTT hay disponibles para la mayoría de los lenguajes, por lo que será necesario que explores las posibilidades para cada caso.

Conclusiones

MQTT es uno de los protocolos más populares dentro del mundo de IoT, por eso es importante que entiendas su funcionamiento para poder desarrollar sistemas y aplicaciones. Para recapitular, en este documento vimos estos temas:

Bibliografía

Licencia

Este material es distribuido bajo licencia Creative Commons BY-SA 4.0. Podés encontrar detalles sobre el uso del material en este link.