IoT MQ設計篇:最終架構與jmqtt介紹

概述

本篇是IoT MQ設計篇的最後一篇,前面分別介紹了一些IoT MQ的基本信息以及趟過的開源項目的坑,本篇主要介紹下我們在經歷一系列問題後確定的最終架構以及我開源的jmqtt項目的介紹:

  1. 最終架構的確定

  2. jmqtt介紹

  3. 爲什麼選擇主主架構

最終架構

在經歷對moquette的深入二次開發後,我們發現仍然有很多需求不能滿足,但是卻掌握了很多基於mqtt協議的開發經驗,鑑於此,我們決定完全進行自研,在自研時,我們提出了幾個基本需求:

  1. 高可用:服務應該是集羣的,保證服務的高可用

  2. 高可擴展性:鑑於對moquette的開發經驗,我們發現可擴展性對後續開發影響非常大,所以設計要合理

  3. 功能:功能非常重要,包括p2p(主要用來即時通訊),黑名單管理,權限認證等。

  4. 數據收集:需要橋接RocketMQ,Kafka進行數據收集

因爲涉及到一些保密信息,這裏只做最簡單的技術架構思想分享,因爲涉及到很多外部組件和定製化開發,相對而言不是很通用並且部署也比較重,後面會具體分享jmqtt的設計和實現,下面是一個簡單的架構圖:

其中最難實現的就是集羣間信息管理,這裏我們分爲了兩種:1.客戶端會話信息(訂閱關係等);2.集羣間消息通信,比如A服務器要把消息發到B服務器上。

  1. 客戶端信息共享主要處理單點連接,訂閱關係保存等,可以採用Redis等中央存儲進行處理

  2. 集羣間消息轉發可以採用Kafka等mq進行處理

前端採用F5/Lvx這樣的負載均衡器進行路由。這種架構需要維護另外的中央存儲集羣以及一個消息轉發集羣,所以維護起來相對比較麻煩,部署依賴也比較多,不是很輕量級,但是設計簡單,同時對於很多管理功能等都很好實現。

jmqtt介紹

jmqtt是我在github上開源的一個mqtt server,使用java及netty實現,目標是實現一個java版的高可用,高擴展,插件化,輕量級的Broker,開箱即用。下面是一個Jmqtt的設計圖:

 

client主要通過負載均衡連接到每個broker上,從而進行消息的傳輸等,Jmqtt與上面的架構設計不同的地方有:

  1. 部署更輕量級,依賴更少,只需要部署Jmqtt broker就可以,不需要額外的服務集羣

  2. 存儲目前使用Rocksdb使用,集羣計劃採用jgroup實現(開發中)

  3. 權限認證,集羣消息傳輸,集羣數據共享,消息持久化等都是插件化的,方便二次開發

  4. 後續計劃與其他IoT 協議實現數據互通(計劃)

目前Jmqtt已完整實現單機功能,正在實現集羣和運維功能管理,詳情請參考:https://github.com/Cicizz/jmqtt

爲什麼選擇主主架構

這兩種架構的設計其實與市場上很多其他的架構設計都很相似,比如emq,hivemq等,我們可以看到這樣的架構都是主主架構,相應的,爲什麼不選擇主從架構或主備架構呢。我們先看一下主主架構與和兩種架構的區別:

  1. 主主:所有的服務都是對等的,都對外提供服務,包括存儲,計算等,也就是 數據分散集羣

  2. 主從/主備:主機對外提供服務,從機或備機一般作爲冗餘處理,例如從機提供讀,備機只是數據備份,也就是 數據集中集羣

像mqtt協議,是客戶端直連到mqtt服務器,客戶端即要發送消息也要接收消息,並且,像RocketMQ或Kafka都有一個服務發現與註冊中心提供給客戶端來進行服務的發現(RocketMQ是namesrv,Kafka是ZK),而mqtt協議的客戶端是沒有這一項的,所以使用主從/主主並不合適,如果對於數據的可靠性要求很高,可以在存儲層做備份處理即可。

上面說了選擇jmqtt以及爲什麼大多數mqtt broker都是主主架構,結合jmqtt再分析一下這三種架構的優缺點:

  1. 主主架構 :優點是實現相對簡單,前端直接用負載均衡器即可,但是例如jmqtt,數據只會存儲到一臺服務器上,然後再需要時再複製到其它服務器上,所以會存在單點故障問題,主主之間無狀態,所以不用考慮切換等問題。只需要客戶端重新進行復雜均衡即可。

  2. 主從(互備式) :例如Kafka,每臺broker按分區來看,有可能是master,也可能是slave,設計比較複雜,但是數據可靠性比較高,並且對機器利用也很高,缺點是實現很複雜,包括服務的切換,數據複製時機等等都需要考慮

  3. 主從(獨立式) :例如RocketMQ,RocketMQ一般是一主一從式,如果主機掛掉了,從機只提供讀服務,然後同一集羣的其它主機再提供其它服務,不需要主從切換,實現相對互備式更加簡單,也不需要自動切換,這也是RocketMQ去ZK選擇自研namesrv進行管理的一個理由,更加輕量級,並且namesrv是無狀態的。

結語

這是IoT MQ設計篇的最後一篇,後面將繼續分享在IoT MQ(主要是jmqtt)的具體實現以及對一些難點問題的思考和解決方案。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章