前言
我们在Nodejs业务逻辑复杂的时候,很难做到完全没有内存泄漏,和出现uncaughtException
的异常情况。这时候,偷懒的办法就是让服务进程再超过一定内存阈值时候进行重启。
直接kill进程的方法是不推荐的,因为会影响正在处理中的request。在处理cluster模式下,node对每一个fork出的子进程提供了优雅退出方式
cluster.worker.disconnect()
他会保证子进程退出前处理所有正在进行中的request。
Nodejs在内存超限时重启
//in memory.js
var cluster = require('cluster');
var usage = require('usage');
var os = require('os');
var CPU_COUNT = process.env.CPU_COUNT;
var CHECK_INTERVAL = process.env.CHECK_INTERVAL;
var cpuCount = CPU_COUNT || os.cpus().length;
var checkInterval = CHECK_INTERVAL || 5000;
module.exports = {
run: function(bytes, runFunc, cleanFunc) {
if (cluster.isMaster) {
for (var i = 0; i < cpuCount; i++) {
cluster.fork();
}
// isSuicide来判断进程是否是意外退出
cluster.on('disconnect', function(worker) {
console.log('' + worker.id + ' disconnect, restart now');
worker.isSuicide = true;
cluster.fork();
});
cluster.on('exit', function(worker) {
if (worker.isSuicide) {
console.info('process exit by kill');
} else {
console.info('process exit by accident');
cluster.fork();
}
console.info('process exit');
});
} else {
runFunc && runFunc();
var checkTimer = setInterval(function() {
usage.lookup(process.pid, function(err, result) {
if (result === null || result === undefined) {
console.log("memory check fail");
return;
}
if (parseInt(result.memory) > bytes) {
console.log("memory exceed, start to kill");
//注意点A
var killtimer = setTimeout(function() {
console.info("process down!")
process.exit(1);
}, 5000);
killtimer.unref();
cleanFunc && cleanFunc();
try {
if (['disconnected', 'dead'].indexOf(cluster.workder.state) < 0) {
cluster.worker.disconnect();
}
} catch (err) {};
clearInterval(checkTimer);
}
});
}, checkInterval);
}
}
}
Nodejs在遇到未知的错误时候优雅重启
请使用graceful模块。
网友评论