我最近在整理以前讀過的書。
這篇想寫《物聯網系統開發:從 0 到 1 構建 IoT 平台》。

這本書對我幫助滿大,尤其是公司決定要引進 MQTT 的時候。
以前對 IoT 的想像其實滿簡單的。
設備連上來,publish message,backend subscribe,資料進 DB。
聽起來好像沒有很難。
但看完這本書後,會發現真正麻煩的地方根本不是「怎麼連上」。
而是設備連上之後,會開始出現一堆很現實的問題。
設備會離線。
網路會抖。
client 可能很慢。
設備電量可能很小。
topic 可能很長。
權限不能每次都查 DB。
command 也不是送出去就代表真的被收到。
這本書讓我覺得有用的地方,是作者有超過十年 IoT 大廠經驗。
所以它不是只在講 MQTT spec,而是會把一些真的上線後才會遇到的問題攤開來。
例如 ACL cache。
如果是一般 backend,我可能會直覺想說:每次 publish / subscribe 都去 DB 查一下權限,很合理吧。
但 IoT 不是幾個使用者按按鈕。
它可能是大量設備一直送資料。
每次都查 DB,聽起來就很快會爆。
這裡我後來也補了一個實務上的對照。
MQTT 5 是 protocol,EMQX cache 是 broker implementation 的設計,這兩個要分清楚。
MQTT 5 提供的是像 session expiry、enhanced authentication、user properties 這類協議層能力,讓 broker 有更多上下文可以利用。
但 ACL cache、authorization cache、external resource cache 這些,通常是 broker 為了扛住大量設備請求而做的實作設計。
像 EMQX 這類 broker,也可以看到類似的設計。
它有 authorization cache,可以把授權結果存在 client session 裡。
同一個 client 在同一段連線內,如果 publish / subscribe 命中已經檢查過的規則,就不用每次重新跑完整 authorization check。
如果授權資料來自 MySQL、MongoDB、Redis 這類外部資料源,也可以透過 external resource cache,避免 broker 一直反覆打後面的資料庫或服務。
Shared Subscription 也讓我有感,因為這個在開發階段很容易忘掉。
以前想到 backend subscribe,我可能會想成一個服務訂閱 topic,然後把資料寫進 DB。
開發環境通常只有一個 backend instance,所以一切看起來都很正常。
但真的上線後,你很可能會有多個 consumer、multiple pods、或多個 worker 一起處理設備資料。
這時候 Shared Subscription 就變得很重要。
它有點像 consumer group。
多個 backend worker 可以加入同一個 shared group,broker 會把 message 分配給其中一個 worker。
例如 $share/backend-workers/device/+/telemetry。
還有 tag 下發 command。
以前想到 command,我可能會想成「對某一台設備下指令」。
但現實通常不是這樣。
你可能是對某個產品、某個地區、某個 firmware version、某一群設備做操作。
這時候 tag 就不只是分類,而是操作邊界。
書裡還提到 tag version。
這點我覺得滿有趣,因為它有點像 DB 裡的 optimistic lock。
你要知道自己是基於哪一版 tag 規則在下 command,不然可能就會用過期的條件操作一批設備。
這種細節如果只是看 MQTT spec,大概不會想到。
Topic Alias 也滿有感。
以前看到 topic 很長,我可能只會覺得命名清楚也不錯。
但 IoT 裡,如果設備很多、上報頻率高、網路又不是很穩,每次都帶完整 topic 其實就是 bandwidth 成本。
MQTT 5.0 的 Topic Alias 可以用比較短的 alias 代替長 topic。
這在一般 web backend 可能沒什麼感覺,但在設備場景裡就很合理。
Inflight Window 也是。
不是每個 client 的網路都很好。
如果 client 很慢,你還一直塞訊息給它,最後不是它爆,就是 broker 要幫它扛一堆狀態。
所以不是 QoS 開高一點就萬事大吉。
可靠性本身也有成本。
書裡甚至還談到 CoAP。
這也提醒我,不是所有設備都適合 MQTT。
有些設備電量很小、網路能力很弱,大部分時間可能都在睡覺。
這時候比較輕量、基於 UDP 的 CoAP 反而可能更適合。
也就是說,IoT 平台不是選一個協定就結束。
你要一直回到設備本身:
它有多少電?
它網路穩不穩?
它會不會離線?
它收到 command 後需不需要回應?
如果沒有回應,是設備沒收到,還是收到了但還沒處理?
我讀這本書最大的收穫是:
MQTT 的難點不是連線。
連線只是開始。
真正難的是設備進到真實世界後,平台還能不能維持一個可信的狀態。
誰在線。
誰離線。
哪些權限還有效。
哪個 command 真的送到了。
哪些資料只是晚到。
哪些指令已經過期,乾脆不要再送。
這也是我覺得 Old School 讀書還是有用的原因。
有些坑不是查一個答案就會遇到。
你要跟著一個真的做過很多年的人,把系統從連線、認證、授權、訊息、資料、維運一路走過一次,才會慢慢知道。