Closed iamso1 closed 5 years ago
更新: 我嘗試了將所有程式碼都砍掉 只剩下socket端 在收到data時 馬上將data回傳 client送資料的頻率是10秒一次 發現儘管是這樣做記憶體還是會不斷上升(client 1秒一次的效果更明顯)
目前情境client連接到socket後並不會中斷 會一直連著 發現網路上也有人是同樣問題 請問這會是nodejs本身的bug嗎? 是否有人也有遇到同樣情況有解掉的呢 謝謝
const socketServer = net.createServer(function(connection) {
const connectSrcIp = connection.remoteAddress;
connection.on('data', function(data) {
console.log(`[hearbeat] mac: ${Date.now()}`);
connection.write(data);
});
connection.on('close', function() {
connection.removeAllListeners();
});
connection.on('error', function() {
console.log('socket error, lose connection');
});
connection.setTimeout(30000, () => {
console.log('close redundant socket');
connection.end();
});
});
node version ?
如果想關閉不活躍的連結可用socket.setTimeout
但要記得.end() & destroy()
conn
.on('timeout', () => {
disconn(conn);
})
.on('error', (err) => {
disconn(conn, err);
})
function disconn(socket, err) {
if(conn.writable) {
conn.end();
return;
}
conn.destroy(err);
}
node version ? 如果想關閉不活躍的連結可用
socket.setTimeout
但要記得.end() & destroy()conn .on('timeout', () => { disconn(conn); }) .on('error', (err) => { disconn(conn, err); }) function disconn(socket, err) { if(conn.writable) { conn.end(); return; } conn.destroy(err); }
@victor0801x 您好 我使用的是8.9.3唷 我有使用settimeout去關閉不活躍的socket 不過只有end 沒有destroy 如果沒有destroy 這socket還會存在嗎?
另外 在這次測試的情境中 因為我不會中斷它 會一直連接著 且送資料 所以我在範例就沒有寫我settimeout這段
https://nodejs.org/dist/latest-v11.x/docs/api/net.html#net_socket_end_data_encoding_callback
Half-closes the socket. i.e., it sends a FIN packet. It is possible the server will still send some data.
我想這篇的解釋對你應該有幫助 https://stackoverflow.com/a/52927597/3195525 .end()能正常關閉socket的前提是雙方都還正常,適用於graceful terminate .destroy()則強制關閉
function close_socket(socket) {
if(conn.writable) {
conn.end();
}
conn.destroy();
}
@victor0801x 了解 感謝您的回覆
回到這個例子 我確定連線沒有中斷 但是還是會繼續長...
初步觀察情況 記憶體仍會上升 其中rss會一直上升 但heaptotal 跟 heapused卻保持穩定
我從下午1點跑到11點一直維持在23~25mb 不過我沒用node-schedule跑改用setInterval
"use strict";
const is_gc_enable = process.env.GC ? true : false;
var net = require('net');
const schedule = require('node-schedule');
const moment = require('moment');
var server = net.createServer(function (socket) {
socket
.pipe(socket)
.on('error', function () {
console.log('socket error, lose connection');
});
});
server.listen(3001, 'localhost');
print_mem_info();
setInterval(() => {
if (is_gc_enable) {
global.gc();
}
print_mem_info();
}, 60 * 1000);
function print_mem_info() {
const memory = process.memoryUsage();
console.log(
moment().format('YYYY/MM/DD HH:mm:ss'),
'rss',
memory.rss / (1024 * 1024),
'heapTotal',
memory.heapTotal / (1024 * 1024),
'heapUsed',
memory.heapUsed / (1024 * 1024),
'external',
memory.external / (1024 * 1024),
);
}
手動gc也維持在20~24左右 應該不是node的問題
不確定程式碼是如何運做, 通常 memory leak 發生點如果在自己變數 scope 的問題為最大宗,建議可以重新掃一下 variable 是不是有某個變數一直在增大當中。
另外,如果是 memory leak 的問題,其實開了 gc 也沒有用,gc 的速度會跟不上 memory 使用成長
@victor0801x 不好意思, 請問方便詢問您的使用環境嗎? 使用的linux版本 以及 node版本
我後來放了一天多 其中也是會有上升下降的情況 但是最後memory總共上升了8mb
不確定程式碼是如何運做, 通常 memory leak 發生點如果在自己變數 scope 的問題為最大宗,建議可以重新掃一下 variable 是不是有某個變數一直在增大當中。
另外,如果是 memory leak 的問題,其實開了 gc 也沒有用,gc 的速度會跟不上 memory 使用成長
@clonn 請問~在自己變數scope的意思是什麼呢? 是否有可以檢查的方式? 我跑了 測試專案 仍會有記憶體上升的問題
另外,如果是 memory leak 的問題,其實開了 gc 也沒有用,gc 的速度會跟不上 memory
是的,而且leak是無法回收的
我只是想說應該不是delay gc造成短期間memory上升
@iamso1 我是用node 10.15.1 on centos 7.6
@victor0801x 感謝您的回覆 我後來觀察比較長的時間後(兩天左右) 發現前面雖然會一直上升 但是上升到一定的記憶體後就會趨於穩定 (會上升 但是會自動再回收下降)
自己回覆一下發生memory leak的問題: 是因為使用了 node-mariasql 套件 該套件本身存在memory leak問題 因此不是 net模組造成的問題
@iamso1 歡迎改用 MariaDB Node.js connector
目的
我希望可做一個簡單的socket 應用
使用的工具
node.js 8.9.3 pm2
操作流程
使用pm2執行 socket server端服務 (pm2 start app.js) 並測試三種case:
遇到的問題
透過pm2 ls 觀察目前執行緒所佔的資源 發現socket server端的記憶體不斷上升 最終crash重啟
測試case 1 發現在沒有client連接的情況下 記憶體就會一直上升(每分鐘0.5M左右的速度) 測試case 2 發現會加速server端記憶體暴增的速度 測試case 3 發現client連接上時 server記憶體會上升 關掉後server記憶體偶爾會釋放 大多都是繼續維持剛剛佔用的記憶體
嘗試過的解法
看error log 曾發現過maxlistener 提示會造成memory leak的問題 將socket server端監聽事件的程式碼調動後即沒有看到此情況發生 先前是將close之類的listener寫在connect的block裡面 移出來後已解決 雖然已經沒有看到警告訊息 但是記憶體仍會上升
參考了一篇不錯的文章 https://cnodejs.org/topic/58eb5d378cda07442731569f 檢查了其中提到的case 自己應該是沒有發生 且使用文章中的工具查測也沒有看到memory leak的情況
因此想請問一下各位大大是否有什麼方向可建議 謝謝
目前正在嘗試的做法
嘗試重新寫一個最精簡的socket server端程式測試是否會有同樣情況發生
2/28更新