เจาะลึกโปรโตคอล MQTT แบบ Lightweight สำหรับระบบเรียลไทม์ - เทียบกับ HTTP Polling และ WebSocket, ใช้งานจริงกับ Node.js + Python, เลือก Broker (Mosquitto/EMQX/AWS IoT Core), Topic Hierarchy + QoS + High Availability Best Practices
MQTT (Message Queuing Telemetry Transport) เป็นโปรโตคอลการสื่อสารข้อมูลแบบ Publish/Subscribe ที่มีน้ำหนักเบา ออกแบบมาสำหรับสภาพแวดล้อมที่เครือข่ายมีแบนด์วิดท์จำกัดและต้องการความหน่วงต่ำ บทความนี้เจาะลึกหลักการทำงาน การใช้งานจริงกับ Node.js และ Python และเปรียบเทียบกับการไม่ใช้ MQTT ในระบบเรียลไทม์
หลักการทำงานพื้นฐานของ MQTT
MQTT ทำงานบน TCP/IP แบ่งสถาปัตยกรรมเป็น 2 ส่วนหลัก: Client (อุปกรณ์/แอปพลิเคชัน) และ Broker (เซิร์ฟเวอร์ตัวกลาง)
- Publish/Subscribe Pattern: Client ฝั่งผู้ส่ง Publish ข้อความไปยัง Topic บน Broker แล้ว Broker กระจายไปยัง Client ทุกตัวที่ Subscribe Topic นั้น - แทนที่จะร้องขอแบบ HTTP Request/Response ตรง ๆ
- Last Will and Testament (LWT): แจ้งเตือนทันทีเมื่อ Client ขาดการเชื่อมต่ออย่างกะทันหัน
- Retained Messages: จัดเก็บข้อความล่าสุดของ Topic ไว้ให้ Subscriber ใหม่รับสถานะล่าสุดได้ทันที
การ Integrate กับ Tech Stack
Node.js (Backend & Real-time Web)
ใช้ไลบรารี mqtt.js เหมาะกับสถาปัตยกรรม Event-driven ของ Node.js ที่ต้องจัดการ I/O จำนวนการเชื่อมต่อสูง มักใช้เป็น WebSocket Bridge ระหว่าง Web Frontend กับ MQTT Broker
Python (Data Processing & Workers)
ใช้ไลบรารี paho-mqtt เป็น Background Workers เพื่อ Subscribe รับข้อมูลมากมายมา Filter บันทึกลงฐานข้อมูล หรือส่งต่อให้ระบบ Machine Learning ประมวลผล
Broker Options
| Broker | เหมาะกับ | จุดเด่น | ข้อจำกัด |
|---|---|---|---|
| Mosquitto | โปรเจกต์เล็ก-กลาง | ทรัพยากรต่ำมาก | ไม่รองรับ Distributed Cluster |
| EMQX | Enterprise | รองรับล้าน Concurrent Clients (Erlang) | ซับซ้อนกว่าในการ Setup |
| AWS IoT Core | Cloud Managed | Auto-scaling + Rule Engine (Lambda/DynamoDB) | Lock-in กับ AWS |
| HiveMQ Cloud | Cloud Managed | Fully Managed + MQTT 5.0 | ราคาสูงกว่า Self-hosted |
กรณีศึกษา: ระบบเรียลไทม์ที่ซับซ้อน
ระบบแชท (Chat Application)
- ผู้ใช้ Subscribe
chat/rooms/{room_id}เพื่อรับข้อความ - ใช้ LWT จับสถานะ Online/Offline ของผู้ใช้ได้ทันที
- ใช้ Retained Messages สำหรับสถานะ "กำลังพิมพ์..." ให้ผู้ใช้ใหม่เห็นได้ทันที
ระบบติดตามพิกัดยานพาหนะ (Fleet Tracking)
- รถอัปเดต GPS ทุก 1 วินาทีผ่าน
fleet/trucks/{id}/location - แอปฝั่งผู้ดูแล Subscribe เพื่อวาดตำแหน่งบนแผนที่แบบเรียลไทม์
- ใช้ QoS 0 เพราะพิกัดถัดไปสำคัญกว่าพิกัดที่ตกหล่น
เปรียบเทียบ: ใช้ MQTT vs ไม่ใช้ MQTT
| มิติ | HTTP Polling | WebSocket ล้วน | MQTT |
|---|---|---|---|
| Header Overhead | หลายร้อยไบต์/คำขอ | เล็กหลัง Handshake | 2 ไบต์ |
| แบตเตอรี่อุปกรณ์ | สูงมาก (Poll ซ้ำ ๆ) | ปานกลาง | ต่ำ |
| Routing/Topic | ไม่มี | ต้องเขียนเอง | มีในตัว |
| QoS/ACK | ไม่มี | ต้องเขียนเอง | 3 ระดับ |
| Reconnect + LWT | ไม่มี | ต้องเขียนเอง | มีในตัว |
Best Practices สำหรับ Production
1. Topic Hierarchy
วางโครงสร้างจากใหญ่ไปเล็ก: [application]/[version]/[entity_type]/[entity_id]/[action]
// ตัวอย่างที่ดี
rideapp/v1/drivers/drv-99/location
rideapp/v1/rooms/room-42/messages
// ห้ามขึ้นต้นด้วย /
/chat/rooms/... // สร้าง root ว่างเปล่า
2. การเลือก QoS ให้เหมาะกับงาน
- QoS 0 (At most once): GPS, เซ็นเซอร์ - ข้อมูลถัดไปสำคัญกว่าที่ตกหล่น
- QoS 1 (At least once): ข้อความแชท, คำสั่งเปิด-ปิด - รับซ้ำได้ถ้า Idempotent
- QoS 2 (Exactly once): ธุรกรรมการเงิน - ไม่หายไม่ซ้ำ แต่ Latency สูงสุด
3. High Availability
- Broker Clustering: กระจายบนหลาย Availability Zones - เซิร์ฟเวอร์ล่ม เซิร์ฟเวอร์อื่นรับช่วงต่อทันที
- Load Balancing: วาง NLB (TCP/TLS) หน้า Broker Cluster + Proxy Protocol สำหรับดึง IP จริงของ Client
- TLS Offloading: ถอดรหัส SSL/TLS ที่ Load Balancer แทน Broker - ลดภาระ CPU เพิ่ม Concurrent Connections ได้
ข้อจำกัดที่ต้องรู้
- Web Browser: เบราว์เซอร์ไม่รองรับ TCP ตรง - ต้องใช้ MQTT over WebSockets เสมอ
- Wildcard: ใช้ + และ # ได้เฉพาะฝั่ง Subscribe เท่านั้น ห้ามใช้ใน Publisher
สำหรับทีมที่กำลังออกแบบระบบเรียลไทม์ที่ต้องรับจำนวนอุปกรณ์/ผู้ใช้จำนวนมากพร้อมกัน MQTT ไม่ใช่แค่ทางเลือกที่ประหยัดแบนด์วิดท์ แต่เป็นการตัดความซับซ้อนของ Message Routing ออกจากโค้ดของคุณไปให้ Infrastructure จัดการ - ซึ่งหมายถึงโค้ดที่สั้นลง Bug ที่น้อยลง และ Time-to-market ที่เร็วขึ้น

