[Node.js] Socket.io + MQTT = Memory leak?!

  • 1115
  • 0

Socket.io + MQTT = Memory leak?!

因業務需求而踏入了Node.js這完全陌生的領域。

 

新手的起手式不外乎參考各前輩的範例,

爬了一堆文後參考超圖解物聯網IoT實作入門的一段範例:

這寫法確實達到了我的需求:收到MQTT訊息後,用Socket.io更新畫面資訊。

但系統運行中總是三不五時就會出現node的抱怨:

接著就會看到記憶體用量不停的暴增,

然後...他就死了。

PM2重開後撐不了幾個小時就會死掉,

嚴重的時候甚至要整台server重啟才行。

這個嚴重的Memory leak困擾了一個月左右,

這一個月真是提心吊膽,

每天睜開眼第一件事就是拿手機開網頁...

 

找了每個可能發生問題的地方都一無所獲,

原本一直在懷疑是Socket.io,

但它的寫法就這麼簡單,

看起來沒什麼能寫錯的地方,

MQTT的寫法也就這麼簡單,

看起來也沒什麼能寫錯的地方,

所以到底是哪出問題了?

 

後來我家聰明的PM大人提供了一個可能可以嘗試的方法:把Socket.io和MQTT分開。

因為他在漫長的搜索答案當中看到了不把MQTT包在Socket.io的寫法。

好吧,死馬當做活馬醫了。

(其實我本身是滿懷疑這方法能行嗎? 畢竟人家那本書似乎賣得不錯,這麼寫的人應該也不少,沒看到相關的問題啊?)

 

於是動手把Code改成這樣:

var sio = io.listen(server);

/*MQTT*/
client.on('message', function (topic, msg) {
    sio.emit('mqtt', {'msg': msg.toString()});
});

/*Socket.io*/
sio.on('connection', function(socket){
    socket.emit('sio', { 'msg': 'data'});
});

P.S:sio.emit 和 socket.emit 雖然都可以傳送資料,但還是有些微差別,詳細內容請至Socket.io網站研究

 

就這樣,再也沒有發生記憶體暴增的問題了!

說真的,我到現在還是不知道為什麼這樣就能解掉這問題?

我猜也許是MQTT發送頻率不同造成?

我們的案子中MQTT是一秒發送一次,

可能是因為太密集造成記憶體回收來不及?

 

如果有大大知道為什麼,

還請不吝指教,謝謝!