在node.js/express中使用异步作业正常关闭

vltsax25  于 2023-02-21  发布在  Node.js
关注(0)|答案(2)|浏览(244)

我正在尝试使用express 4.xhttp服务器在node.js中进行正常关闭。
关闭express服务器很容易,但让我担心的是,我们有很多异步作业。
1.接收请求
1.做点什么
1.将响应发送回客户端
1.在后台继续执行一些与该请求相关的异步操作,例如向某个第三方服务发出另一个请求
1.接收来自第三方服务的响应并将响应保存到数据库等。
1.结束
如果我把我的优雅关机代码写成这样:

process.on('SIGTERM', function () {
    serverInstance.close(function(){
        closeConnectionToDatabases(function(){
            process.exit(0);
        })
    });

    // shutdown anyway after some time
    setTimeout(function(){
        process.exit(0);
    }, 8000);
});

如果SIGTERM发生在上面解释的流程的第一步和第二步之间,我怎么能确定一切正常呢?第四步,第五步和第六步呢?有没有什么好的方法来处理这个问题,或者只是手动监视所有来自你的服务的请求,并等待它们?
谢谢,伊万

fae0ux8s

fae0ux8s1#

process.exit()将立即终止node.js进程,而不等待所有aync任务完成。
如果你想要一个真正的正常关机,你应该手动关闭所有资源(所有打开的连接和文件描述符),而不是调用process.exit()。在这种情况下,node.js将在完成所有挂起的异步任务后立即终止。
因此,只需关闭所有数据库连接和其他I/O资源:

process.on('SIGTERM', function () {
    serverInstance.close(function(){
        closeConnectionToDatabases(function(){
            // now node.js should close automatically
        })
    });

    // shutdown anyway after some time
    setTimeout(function(){
        process.exit(0);
    }, 8000);
});
q0qdq0h2

q0qdq0h22#

这里有一个更好的选择:
我们可以创建一个新的Promise,并在异步作业完成时解决它,而不是使用setTimeout来等待所有异步作业完成,然后在解决了Promise之后,我们可以退出进程。

process.on('SIGTERM', () => {
  new Promise((resolve) => {
      serverInstance.close(async () => {
        await closeConnectionToDatabases();
        resolve();
      });
  }).then(() => process.exit(0))
});

希望对你有帮助:)

相关问题