You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Express中是否存在Fastify.addHook('onClose', () => {})的等价实现?

Express应用退出时执行操作的多种解决方案

除了你已经尝试的process.on('exit'),还有几种更灵活的方案,适合不同场景下的优雅退出和资源清理:

1. 监听系统终止信号(SIGINT/SIGTERM)

process.exit事件触发时,Node.js已经进入退出流程,异步操作可能无法完成。监听系统信号可以提前捕获退出请求,执行异步清理后再主动退出:

const server = app.listen(3000);

// 捕获Ctrl+C触发的SIGINT信号
process.on('SIGINT', async () => {
  console.log('收到终止信号,开始优雅退出');
  
  // 先停止HTTP服务器,拒绝新请求,处理完现有请求
  server.close(async () => {
    console.log('HTTP服务器已停止');
    // 执行异步清理:关闭数据库连接、释放文件锁等
    await dbConnection.close();
    await releaseResources();
    console.log('清理完成,应用退出');
    process.exit(0);
  });
});

// 捕获系统发送的SIGTERM信号(如Docker stop、systemd stop)
process.on('SIGTERM', async () => {
  console.log('收到系统终止信号');
  await gracefulShutdown(server);
  process.exit(0);
});

// 封装优雅退出逻辑
async function gracefulShutdown(server) {
  server.close();
  await dbConnection.close();
  console.log('资源已全部释放');
}

2. 监听HTTP服务器的close事件

如果你需要在HTTP服务器完全关闭后执行操作,可以直接监听server实例的close事件:

const server = app.listen(3000);

server.on('close', () => {
  console.log('HTTP服务器已关闭,所有现有请求处理完成');
  // 这里可以做同步清理操作
  clearInterval(heartbeatInterval);
  console.log('定时任务已清除');
});

// 需要主动调用server.close()才会触发close事件,通常结合信号监听
process.on('SIGINT', () => {
  server.close();
});

3. 处理异常退出场景

针对未捕获的异常或未处理的Promise拒绝,也可以添加监听来执行紧急清理:

// 捕获未捕获的同步异常
process.on('uncaughtException', (err) => {
  console.error('未捕获异常:', err.stack);
  // 紧急清理(尽量用同步操作,避免异步不确定性)
  fs.writeFileSync('crash.log', `崩溃时间: ${new Date()}\n错误信息: ${err.stack}`);
  process.exit(1);
});

// 捕获未处理的Promise拒绝
process.on('unhandledRejection', (reason, promise) => {
  console.error('未处理的Promise拒绝:', reason);
  // 执行必要清理后退出
  process.exit(1);
});

4. 第三方工具简化(可选)

如果不想手动管理多个信号监听,可以用exit-hook这类库帮你统一处理退出逻辑:

const exitHook = require('exit-hook');

// 注册同步清理
exitHook(() => {
  console.log('应用即将退出,执行同步清理');
});

// 注册异步清理
exitHook(async () => {
  await dbConnection.close();
  console.log('数据库连接已关闭');
});

这个库会自动监听SIGINT、SIGTERM等信号,以及process.exit事件,无需手动绑定每个信号。


内容的提问来源于stack exchange,提问作者Mark G

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 17:52:27