我希望有一个运行带有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}));
当节点未在容器中运行时,这很有效。当它在容器中并且我杀死容器时,不执行清理。我想在我可以进行清理之前,容器正在杀死所有通信管道。有想法该怎么解决这个吗 ?
答案 0 :(得分:1)
你需要听SIGTERM
。当您运行docker stop <container>
时,它会向容器发送SIGTERM
并等待10秒钟。如果容器没有同时停止,它将向内核发送SIGKILL
以完成容器。
推荐参考:Gracefully Stopping Docker container
因此,从内部容器中,您应该听取SIGTERM
。从外部,您可以使用docker API检查您的容器是否已被杀死并执行正确的工作:Monitoring Docker Events