
EMQ中CPU是公平配置設定給MQTT會話,大量pub消息到一個訂閱,訂閱不會拿到更多cpu,最終導緻消息累積,記憶體溢出當機。
最好的解決辦法是分組訂閱,把消息打散,多個用戶端訂閱。
問:請問一下,我現在的業務就是隻使用一個sub,主題是\hello\#,去訂閱數萬個終端消息。請問針對這個問題,如何來優化業務邏輯?可以通過增加sub的方式嗎?即把數萬終端分成幾個小組,每小組往一個主題pub,然後再分别訂閱?
答:不需要自己實作,使用emq 2.x的本地+共享訂閱相結合即可。使用主題:$local/$share/group/topic
http://emqtt.com/docs/v2/advanced.html#local-subscriptionemq2.x版本,共享訂閱隻支援單節點,不支援叢集。
---
關聯閱讀:我的mqtt協定和emqttd開源項目個人了解(24) - emq v2.3.11源碼成熟度如何?
EMQ 2.3中的本地/共享訂閱
簡介
使用本地訂閱後,指消息隻在訂閱者的本地(所連接配接的)EMQ節點,不會流傳到叢集中的其它EMQ節點中。在共享訂閱中,訂閱同一個主題的用戶端會輪流的收到這個主題下的消息,也就是說同一個消息不會發送到多個訂閱者,進而實作訂閱端的多個節點之間的負載均衡。共享訂閱對于資料采集/集中處理類應用非常有用。在這樣的場景下,資料的生産者遠多餘資料的消費者,且同一條資料隻需要被任意消費者處理一次。
EMQ中本地/共享訂閱特性
本地訂閱(Local Subscription)是指隻在本節點建立訂閱與路由表,不會在叢集節點間廣播全局路由。
mosquitto_sub -t '$local/topic'
mosquitto_pub -t 'topic'
使用方式: 訂閱者在主題(Topic)前增加‘$local/’字首。
共享訂閱(Shared Subscription)支援在多訂閱者間采用分組負載平衡方式派發消息:
共享訂閱支援兩種使用方式:
訂閱字首 使用示例
$queue/ mosquitto_sub -t ‘$queue/topic’
$share/<group>/ mosquitto_sub -t ‘$share/group/topic’
其中$queue與$share的差別,在于$share後面可以加不同的分組(group),比如$share/group1/topic,$share/group2/topic,$share/group3/topic,生産者發一個topic的消息,訂閱$share/group1/topic的消費者、$share/group2/topic的消費者、$share/group3/topic的消費者都能收到消息,如果一個分組中存在多個消費者,則多個消費者還會共享訂閱消息,每個group的消息随機其中一個消費者能獲得。
使用場景
當生産者和消費者的消息隻想通過一個EMQ節點,可使用EMQ的本地訂閱。
當消費者的消息想通過EMQ實作訂閱端的多個消費者之間的負載均衡,則可使用EMQ的共享訂閱。
特殊情況下,當多個生産者生産多條消息的時候,一個消費者壓力會很大,分擔一個消費者的壓力,或者其它情況,需要用到本地共享訂閱。本地共享訂閱是本地訂閱與共享訂閱的組合。
下圖為本地共享訂閱的消息走向和訂閱關系。每個消費者都必須本地共享訂閱每一個EMQ節點,這樣每條消息隻會走向一個消費者。注意:這裡的SUB指消費者,PUB指生産者。
消息流向
每個PUB的消息從經過LB(負載均衡),發送到不同的EMQ節點中,比如第一個EMQ節點收到的M1、M3、M4的消息:
通過本地訂閱,這個EMQ節點的消息把收到的M1、M3、M4的消息不發給其它叢集的EMQ節點,隻從這個EMQ節點發送給訂閱的SUB。
通過共享訂閱,這個EMQ的消息把收到的M1、M3、M4的消息發送給不同的SUB端。
通過上述本地訂閱+共享訂閱,實作多個PUB發送的每條消息随機到達一個并且隻有一個SUB。
訂閱關系
每個SUB使用本地共享訂閱($local/$share/A)來訂閱EMQ叢集中的每個EMQ節點。