Using MQTT
The MQTT Essentials series and MQTT Guide 2023 are great places to start in-depth learning. This document only outlines the most important concepts for implementation and serves as a reference for those familiar with MQTT.
Tip
Use MQTTX for a great MQTT testing and development client.
MQTT Brokers
Criteria for evaluation of MQTT brokers
- Latency: How fast can the broker dispatch and deliver an MQTT message from one client to another?
- Performance: How many QoS/0/1/2 MQTT messages per second can the broker route and deliver?
- Reliability: Does the broker support MQTT message persistence and delivery without data loss?
- Security: Does the broker support MQTT over WebSocket and SSL/TLS?
Less relevant items for simple use cases
- Scalability: Can the broker scale horizontally to handle millions of concurrent MQTT connections?
- Availability: Does the broker support highly available clustering for mission-critical applications?
Options
- EMQX - Hugely scalable, overkill for simple use cases, advanced security features
- NanoMQ - Fast, lightweight broker, multi-threaded,
- Rumqttd - Written in rust, less community support and now widely used (not recommended)
- Mosquitto - Single threaded, lightweight, widely used
Of the above brokers, the ones that stand out are EMQX, Mosquitto, and NanoMQ. Below is a head-to-head comparison of non-functional features.
EMQX | Mosquitto | NanoMQ | |
---|---|---|---|
Protocols | MQTT 5.0/3.1.1 MQTT over QUIC | MQTT 5.0/3.1.1 | MQTT 5.0/3.1.1 MQTT over QUIC ZeroMQ & NanoMSG |
Scalability | Excellent | Moderate | Good |
Availability | Excellent | Moderate | Moderate |
Performance | Excellent | Good | Excellent |
Latency | Excellent | Good | Excellent |
Reliability | High | High | High |
Security | Excellent | Excellent | Good |
Integrations | Excellent | Moderate | Moderate |
Compatibility | Good | Excellent | Excellent |
Ease of Use | Good | Excellent | Good |
Community Support | Excellent | Excellent | Excellent |
Concepts
Quality of Service (QoS)
Defines the level of delivery guarantee for a specific message.
- At most once (QoS 0)
- At least once (QoS 1)
- Exactly once (QoS 2)
Implementation & Design Tips
- Use bridging to connect MQTT brokers together and forward messages between them. This can give you a robust and modular framework for connectivity between many devices.
NanoMQ
NanoMQ Tip: If you enabled SQLite feature, NanoMQ will automatically flush cached messages into disk when network is disconnected. NanoMQ will resend cached messages once bridging connection is restored. But each cached message will be resent in a certain interval to avoid bandwidth exhaustion.
Bridging MQTT Brokers
Following the tutorial, the configuration docs, and the nanomq.conf configuration file in the Appendix.
You can validate comms between the broker and bridge with MQTTX test clients
- On MQTTBridge client, subscribe to
fwd/#
. - On NanoMQTest client, publish a message on
topic1
. You should see a message arrive at MQTTBridge. - On NanoMQTest client, subscribe to
topic1
. - On MQTTBridge client, publish a message to
cmd/topic1
. You should see a message arrive at NanoMQTest.
Appendix
RESOURCES
- 🔥 Monitoring MQTT broker with Prometheus and Grafana
- https://dev.to/emqx/a-comprehensive-comparison-of-open-source-mqtt-brokers-2023-a7j
- https://grafana.com/grafana/dashboards/17446-emqx/
- https://nanomq.io/docs/en/latest/quick-start/quick-start.html#experience-the-nanomq-services
nanomq.conf
bridges.mqtt.name {
## TCP URL format: mqtt-tcp://host:port
## TLS URL format: tls+mqtt-tcp://host:port
## QUIC URL format: mqtt-quic://host:port
server = "mqtt-tcp://broker.emqx.io:1883"
## MQTT protocol version(4 | 5)
proto_ver = 4
# username = admin
# password = public
clean_start = true
keepalive = 60s
## Uncomment if you need TLS
## ssl {
## keyfile = "/etc/certs/key.pem"
## certfile = "/etc/certs/cert.pem"
## cacertfile = "/etc/certs/cacert.pem"
## }
forwards = [
{
remote_topic = "fwd/topic1"
local_topic = "topic1"
qos = 1
},
{
remote_topic = "fwd/topic2"
local_topic = "topic2"
qos = 2
}
]
subscription = [
{
remote_topic = "cmd/topic1"
local_topic = "topic1"
qos = 1
},
{
remote_topic = "cmd/topic2"
local_topic = "topic2"
qos = 2
}
]
max_parallel_processes = 2
max_send_queue_len = 1024
max_recv_queue_len = 1024
}
bridges.mqtt.name {
## TCP URL format: mqtt-tcp://host:port
## TLS URL format: tls+mqtt-tcp://host:port
## QUIC URL format: mqtt-quic://host:port
server = "mqtt-tcp://broker.emqx.io:1883"
## MQTT protocol version(4 | 5)
proto_ver = 4
# username = admin
# password = public
clean_start = true
keepalive = 60s
## Uncomment if you need TLS
## ssl {
## keyfile = "/etc/certs/key.pem"
## certfile = "/etc/certs/cert.pem"
## cacertfile = "/etc/certs/cacert.pem"
## }
forwards = [
{
remote_topic = "fwd/topic1"
local_topic = "topic1"
qos = 1
},
{
remote_topic = "fwd/topic2"
local_topic = "topic2"
qos = 2
}
]
subscription = [
{
remote_topic = "cmd/topic1"
local_topic = "topic1"
qos = 1
},
{
remote_topic = "cmd/topic2"
local_topic = "topic2"
qos = 2
}
]
max_parallel_processes = 2
max_send_queue_len = 1024
max_recv_queue_len = 1024
}