要实现优雅退出,需在app.listen()前注册SIGTERM和SIGINT监听器并定义shutdown函数:先关闭HTTP服务器、再释放数据库连接、加10秒超时保护、最后退出进程;同时监听uncaughtException和unhandledRejection以兜底触发shutdown。
☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 多模态理解力帮你轻松跨越从0到1的创作门槛☜☜☜

当Codex服务正在处理HTTP请求或执行数据库事务时突然被kill -9终止,未完成的操作会丢失数据或留下脏状态。要让服务在收到SIGTERM信号后等待当前任务结束再关闭,必须手动实现退出生命周期管理。
注册系统信号监听器
在服务启动后立即注册对SIGTERM和SIGINT的监听,这是优雅退出的前提。Node.js中需使用process.on()绑定事件,不能依赖框架默认行为,因为Express等框架不自动处理进程信号。
执行:process.on('SIGTERM', shutdown); process.on('SIGINT', shutdown);
注意:如果在监听器注册前就收到信号,进程会直接退出,【必须确保这行代码在app.listen()之前执行】。
定义shutdown函数并接管关闭流程
方法一:基础版本(适用于无长时异步任务的场景)
定义async function shutdown() { console.log('收到退出信号,开始关闭服务...'); server.close(() => { console.log('HTTP服务器已关闭'); process.exit(0); }); }
方法二:增强版本(支持等待数据库连接释放与未完成请求)
第一步:调用server.close()停止接收新连接,但已建立的连接仍可继续处理;
通过本地 Codex 或 OpenClaw OAuth 凭证直接调用 ChatGPT/Codex Responses 的 image_generation 工具来生成或编辑光栅图像,然后保存
第二步:设置10秒超时保护,防止某请求卡死导致服务永远不退出;
第三步:等待所有活跃HTTP请求自然结束,同时主动断开MongoDB/Redis连接池;
第四步:确认db.close()和redis.quit()都resolve后再调用process.exit(0)。
这一步不能省略超时控制,否则一个死循环Promise会让整个退出流程挂起。
拦截未捕获异常与拒绝的Promise
process.on('uncaughtException', err => { console.error('未捕获异常:', err); shutdown(); });
process.on('unhandledRejection', (reason, promise) => { console.error('未处理的Promise拒绝:', reason); shutdown(); });
这两个监听器补全了退出兜底路径,避免因异常导致shutdown逻辑跳过。














