Nodejs 优雅退出

2019-10-04  本文已影响0人  黑曼巴yk

前言

我们在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模块。

上一篇 下一篇

猜你喜欢

热点阅读