Docker容器上的清理杀死

时间:2015-12-15 22:31:14

标签: node.js redis docker socket.io

我希望有一个运行带有socket.io的nodejs的多docker容器设置。 我正在使用redis作为一些共享的socketId / state。当我杀死一个nodejs进程时,我执行了一个清理函数来删除与该进程相关的sockeId / state。

process.stdin.resume();//so the program will not close instantly

function exitHandler(options, err) {

console.log('exitHandler');

_.forEach(global.sockets, (socket)=> {
    if (global.redisClient) {
        global.redisClient.hdel('socketA', socket);
        global.redisClient.hdel('socketB', socket);
        global.redisClient.del(`socketC_${socket}`);
    }
});

_.forEach(global.userIds, (userId)=> {
    if (global.redisClient) {
        global.redisClient.hdel('socketD', userId);
        global.redisClient.del(`socketE_${userId}`);
    }
});

if (options.cleanup) console.log('clean');
if (err) console.log(err.stack);
if (options.exit) process.exit();
}

//do something when app is closing
process.on('exit', exitHandler.bind(null, {cleanup: true}));

//catches ctrl+c event
process.on('SIGINT', exitHandler.bind(null, {exit: true}));

//catches uncaught exceptions
process.on('uncaughtException', exitHandler.bind(null, {exit: true}));

当节点未在容器中运行时,这很有效。当它在容器中并且我杀死容器时,不执行清理。我想在我可以进行清理之前,容器正在杀死所有通信管道。有想法该怎么解决这个吗 ?

1 个答案:

答案 0 :(得分:1)

你需要听SIGTERM。当您运行docker stop <container>时,它会向容器发送SIGTERM并等待10秒钟。如果容器没有同时停止,它将向内核发送SIGKILL以完成容器。

推荐参考:Gracefully Stopping Docker container

因此,从内部容器中,您应该听取SIGTERM。从外部,您可以使用docker API检查您的容器是否已被杀死并执行正确的工作:Monitoring Docker Events