[G1-Sync] Manual knowledge update
This commit is contained in:
@@ -0,0 +1,309 @@
|
||||
---
|
||||
id: backend-mqtt-iot
|
||||
title: MQTT — IoT messaging protocol
|
||||
category: Coding
|
||||
status: draft
|
||||
source_trust_level: B
|
||||
verification_status: conceptual
|
||||
created_at: 2026-05-09
|
||||
updated_at: 2026-05-09
|
||||
tags: [backend, iot, vibe-coding]
|
||||
tech_stack: { language: "TS / Python", applicable_to: ["Backend", "IoT"] }
|
||||
applied_in: []
|
||||
aliases: [MQTT, IoT, broker, Mosquitto, EMQX, HiveMQ, AWS IoT, retained message, last will]
|
||||
---
|
||||
|
||||
# MQTT (IoT)
|
||||
|
||||
> IoT 의 표준 protocol. **TCP 위 의 가벼운 pub/sub. QoS 0/1/2. Retained / last will**. Mosquitto / EMQX / AWS IoT.
|
||||
|
||||
## 📖 핵심 개념
|
||||
- Pub/sub via topic.
|
||||
- Topic: hierarchical (`home/livingroom/temp`).
|
||||
- QoS 0 (at most once), 1 (at least), 2 (exactly).
|
||||
- Retained = 마지막 message 가 새 subscriber.
|
||||
|
||||
## 💻 코드 패턴
|
||||
|
||||
### Connect (Node)
|
||||
```ts
|
||||
import mqtt from 'mqtt';
|
||||
|
||||
const client = mqtt.connect('mqtt://broker.hivemq.com', {
|
||||
clientId: 'my-device-' + Math.random(),
|
||||
username: 'user',
|
||||
password: 'pw',
|
||||
will: {
|
||||
topic: 'devices/my-device/status',
|
||||
payload: 'offline',
|
||||
qos: 1,
|
||||
retain: true,
|
||||
},
|
||||
});
|
||||
|
||||
client.on('connect', () => {
|
||||
client.publish('devices/my-device/status', 'online', { qos: 1, retain: true });
|
||||
client.subscribe('home/+/temp'); // wildcard
|
||||
});
|
||||
|
||||
client.on('message', (topic, payload) => {
|
||||
console.log(topic, payload.toString());
|
||||
});
|
||||
```
|
||||
|
||||
### Topic wildcard
|
||||
```
|
||||
+ : single level (home/+/temp)
|
||||
# : multi level (home/#)
|
||||
|
||||
home/livingroom/temp -> matches home/+/temp, home/#
|
||||
home/kitchen/light/dim -> matches home/#
|
||||
```
|
||||
|
||||
### QoS
|
||||
```
|
||||
QoS 0: fire-and-forget (UDP-like).
|
||||
QoS 1: at-least-once (ack 가 보장 — 중복 가능).
|
||||
QoS 2: exactly-once (4-step handshake — 느린).
|
||||
|
||||
→ 대부분 QoS 1.
|
||||
Sensor / 빈번 = QoS 0.
|
||||
Critical = QoS 2.
|
||||
```
|
||||
|
||||
### Retained
|
||||
```ts
|
||||
client.publish('home/temp', '22.5', { retain: true });
|
||||
|
||||
// 새 subscriber 가 sub 즉시 = '22.5' 받음 (retained).
|
||||
```
|
||||
|
||||
→ "현재 상태" 식.
|
||||
|
||||
### Last will
|
||||
```ts
|
||||
const client = mqtt.connect(url, {
|
||||
will: {
|
||||
topic: 'devices/my-device/status',
|
||||
payload: 'offline',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
→ Client crash / disconnect = broker 가 자동 publish.
|
||||
|
||||
### Clean session
|
||||
```ts
|
||||
mqtt.connect(url, { clean: false, clientId: 'persistent-id' });
|
||||
```
|
||||
|
||||
→ Reconnect 시 missed message 받음 (broker 가 queue).
|
||||
|
||||
### Broker
|
||||
```bash
|
||||
# Mosquitto (가장 popular open source)
|
||||
docker run -p 1883:1883 eclipse-mosquitto
|
||||
|
||||
# EMQX (Erlang, 큰 scale)
|
||||
docker run -p 1883:1883 -p 8083:8083 emqx/emqx
|
||||
|
||||
# HiveMQ (commercial / community)
|
||||
```
|
||||
|
||||
### MQTT over WebSocket
|
||||
```ts
|
||||
const client = mqtt.connect('ws://broker:8083/mqtt');
|
||||
```
|
||||
|
||||
→ Browser-friendly (HTML5).
|
||||
|
||||
### MQTT 5.0 features
|
||||
```
|
||||
- Reason code (relevant error).
|
||||
- Topic alias (long topic 의 short).
|
||||
- User properties (custom header).
|
||||
- Shared subscription ($share/group/topic).
|
||||
- Session expiry.
|
||||
```
|
||||
|
||||
### Shared subscription
|
||||
```ts
|
||||
client.subscribe('$share/group1/sensor/temp');
|
||||
// → Group 1 의 1 subscriber 만 받음 (load balance).
|
||||
```
|
||||
|
||||
→ N consumer 가 1 message 만.
|
||||
|
||||
### vs HTTP
|
||||
```
|
||||
HTTP:
|
||||
- Request-response.
|
||||
- 큰 overhead (header).
|
||||
- Stateless.
|
||||
|
||||
MQTT:
|
||||
- Pub/sub.
|
||||
- 작은 overhead (binary).
|
||||
- Persistent connection.
|
||||
|
||||
→ IoT (작은 device, 매 정보 / 연속) = MQTT.
|
||||
```
|
||||
|
||||
### vs WebSocket
|
||||
```
|
||||
WebSocket: protocol layer.
|
||||
MQTT-over-WebSocket: MQTT 의 message 위 WS.
|
||||
|
||||
→ MQTT 가 application protocol.
|
||||
```
|
||||
|
||||
### vs CoAP
|
||||
```
|
||||
CoAP: HTTP-like for IoT (UDP).
|
||||
MQTT: TCP, pub/sub.
|
||||
|
||||
→ CoAP = constrained device.
|
||||
MQTT = 일반.
|
||||
```
|
||||
|
||||
### AWS IoT Core
|
||||
```ts
|
||||
import { mqtt as awsmqtt } from 'aws-iot-device-sdk-v2';
|
||||
|
||||
const builder = awsmqtt.AwsIotMqttConnectionConfigBuilder.new_mtls_builder_from_path(
|
||||
cert, key
|
||||
);
|
||||
builder.with_endpoint('xxx.iot.us-east-1.amazonaws.com');
|
||||
const conn = new awsmqtt.MqttClient().new_connection(builder.build());
|
||||
await conn.connect();
|
||||
```
|
||||
|
||||
→ Managed broker. mTLS auth. Rules engine.
|
||||
|
||||
### Message routing (broker level)
|
||||
```
|
||||
EMQX rule:
|
||||
SELECT * FROM "sensor/+/temp" WHERE payload.value > 80
|
||||
→ save to DB
|
||||
→ alert webhook
|
||||
```
|
||||
|
||||
→ Broker 가 자체 logic.
|
||||
|
||||
### Sparkplug B
|
||||
```
|
||||
Industrial IoT spec.
|
||||
- Birth / death message.
|
||||
- Metric definition (DDATA / NDATA).
|
||||
- Topic structure (spBv1.0/...).
|
||||
```
|
||||
|
||||
→ 큰 industrial automation.
|
||||
|
||||
### MQTT-SN (sensor network)
|
||||
```
|
||||
MQTT 의 UDP version.
|
||||
- 매우 작은 device.
|
||||
- Gateway 가 MQTT broker 와 bridge.
|
||||
```
|
||||
|
||||
### Security
|
||||
```
|
||||
- mTLS (인증).
|
||||
- Username / password (간단).
|
||||
- Token-based (modern).
|
||||
- ACL (topic 별 read/write).
|
||||
- Encryption in transit (TLS).
|
||||
```
|
||||
|
||||
### Use case
|
||||
```
|
||||
- Smart home (Home Assistant)
|
||||
- Industrial IoT (Sparkplug)
|
||||
- Connected car
|
||||
- Asset tracking
|
||||
- Sensor network (temperature, humidity)
|
||||
- Real-time chat
|
||||
- Game (state sync)
|
||||
```
|
||||
|
||||
### Production setup
|
||||
```
|
||||
HA (3+ broker, cluster).
|
||||
Persistence (Redis / DB).
|
||||
Auth (mTLS + token).
|
||||
Monitoring (Prometheus).
|
||||
TLS (Let's Encrypt).
|
||||
Rate limit (per client).
|
||||
```
|
||||
|
||||
### 함정
|
||||
```
|
||||
- QoS 2 가 default 가정: 느린.
|
||||
- Retained 가 항상 사용: 메모리.
|
||||
- Wildcard `#` 가 root: 모든 message.
|
||||
- Auth 없음: 누구나 publish.
|
||||
- ACL 없음: 누구나 모든 topic.
|
||||
- Broker 1 instance: SPOF.
|
||||
```
|
||||
|
||||
### Telemetry pattern
|
||||
```
|
||||
Device → MQTT → Broker → Stream processor → DB / dashboard.
|
||||
|
||||
Example:
|
||||
- ESP32 가 sensor reading.
|
||||
- Broker (EMQX).
|
||||
- Kafka bridge.
|
||||
- TimescaleDB.
|
||||
- Grafana.
|
||||
```
|
||||
|
||||
### Home Assistant
|
||||
```yaml
|
||||
mqtt:
|
||||
sensor:
|
||||
- name: 'Temperature'
|
||||
state_topic: 'home/livingroom/temp'
|
||||
unit_of_measurement: '°C'
|
||||
```
|
||||
|
||||
### Cloud option
|
||||
```
|
||||
- AWS IoT Core
|
||||
- Azure IoT Hub
|
||||
- GCP IoT Core (deprecated)
|
||||
- HiveMQ Cloud
|
||||
- EMQ Cloud
|
||||
- AdafruitIO (작은 hobby)
|
||||
```
|
||||
|
||||
## 🤔 의사결정 기준
|
||||
| 상황 | 추천 |
|
||||
|---|---|
|
||||
| IoT device | MQTT |
|
||||
| 작은 / 간단 | Mosquitto |
|
||||
| 큰 scale | EMQX / HiveMQ |
|
||||
| AWS-native | IoT Core |
|
||||
| Industrial | Sparkplug B |
|
||||
| Web client | MQTT-over-WS |
|
||||
| Constrained UDP | CoAP / MQTT-SN |
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **HTTP poll IoT**: 매우 비효율.
|
||||
- **QoS 2 always**: 느린.
|
||||
- **No auth**: 침해.
|
||||
- **No retained 이전 state**: subscriber 가 모름.
|
||||
- **`#` 매 client**: 폭발.
|
||||
- **No HA broker**: SPOF.
|
||||
|
||||
## 🤖 LLM 활용 힌트
|
||||
- MQTT = IoT 의 표준.
|
||||
- QoS 1 가 sweet spot.
|
||||
- Retained + last will 가 핵심.
|
||||
- EMQX / Mosquitto 가 default broker.
|
||||
|
||||
## 🔗 관련 문서
|
||||
- [[Messaging_Kafka_Patterns]]
|
||||
- [[Backend_NATS_JetStream]]
|
||||
- [[Backend_WebSocket_Scaling]]
|
||||
Reference in New Issue
Block a user