http-graceful-upgrade-shutdown
v1.0.1
Published
gracefully shuts downs http server
Maintainers
Readme
http-graceful-shutdown
English | 简体中文
http-graceful-shutdown 用于优雅关闭 Node.js HTTP 服务。它可以配合原生 http、https、Express、Koa、Fastify、HTTP/2 等服务使用。
特性
- 跟踪所有 HTTP / HTTPS 连接
- 关闭时停止接受新连接
- 尽量通过
connection: close告知客户端服务即将关闭 - 立即销毁没有关联 HTTP 请求的空闲 socket
- 支持自定义清理函数,例如关闭数据库连接
- 支持在关闭 HTTP socket 之前执行
preShutdown - 支持通过系统信号或手动函数触发关闭
- 支持选择强制
process.exit()或等待事件循环自然结束 - 支持保留已完成 HTTP Upgrade 的连接,例如 WebSocket
安装
npm install http-graceful-shutdown快速开始
const gracefulShutdown = require('http-graceful-shutdown');
// app 可以是 http、https、express、koa、fastify 等
const server = app.listen(3000);
// 启用优雅关闭
gracefulShutdown(server);默认会监听 SIGINT 和 SIGTERM。收到信号后,库会停止接收新连接,等待已有请求完成,并在超时后强制关闭剩余连接。
关闭流程
- 服务正常处理客户端请求。
- 进程收到终止信号,例如
SIGINT或SIGTERM。 - 执行
preShutdown,此时 HTTP socket 仍保持可用且未被处理。 - 关闭并销毁空闲连接。
- 阻止新请求进入。
- 如果可能,向客户端发送
connection: close响应头。 - 等待已有 socket 完成;超时后强制销毁剩余 socket。
- 执行
onShutdown,适合做额外清理,例如关闭数据库连接。 - 执行
finally。 - 根据
forceExit配置触发process.exit(),或等待事件循环自然结束。
配置项
| 配置项 | 默认值 | 说明 |
| --- | --- | --- |
| timeout | 30000 | 强制关闭前等待的最长时间,单位为毫秒 |
| signals | 'SIGINT SIGTERM' | 触发关闭流程的信号,多个信号用空格分隔 |
| development | false | 为 true 时跳过优雅关闭流程,便于开发环境快速退出 |
| gracefulUpgrades | false | 为 true 时,普通清理阶段不会销毁已升级连接,会等待其自然关闭或直到超时 |
| rejectNewConnectionsOnSignal | false | 为 true 时,收到关闭信号后立即拒绝新连接,不等待 preShutdown 结束 |
| preShutdown | - | 可选异步函数,需返回 Promise;执行时 HTTP socket 仍可用且未被处理 |
| onShutdown | - | 可选异步函数,需返回 Promise;用于执行额外清理 |
| forceExit | true | 为 true 时关闭结束后调用 process.exit();否则等待事件循环自然结束 |
| finally | - | 可选同步函数,在关闭流程末尾执行,函数应尽量短小 |
高级用法
const gracefulShutdown = require('http-graceful-shutdown');
const server = app.listen(3000);
function preShutdownFunction(signal) {
console.log('收到关闭信号:' + signal);
return Promise.resolve();
}
function shutdownFunction(signal) {
return new Promise((resolve) => {
console.log('开始清理资源,信号:' + signal);
setTimeout(() => {
console.log('资源清理完成');
resolve();
}, 1000);
});
}
function finalFunction() {
console.log('服务已优雅关闭');
}
gracefulShutdown(server, {
signals: 'SIGINT SIGTERM',
timeout: 10000,
development: false,
forceExit: true,
gracefulUpgrades: false,
rejectNewConnectionsOnSignal: false,
preShutdown: preShutdownFunction,
onShutdown: shutdownFunction,
finally: finalFunction
});手动触发关闭
gracefulShutdown(server, options) 会返回一个函数,可用于测试或自定义关闭入口。
let shutdown;
beforeAll(() => {
shutdown = gracefulShutdown(server);
});
afterAll(async () => {
await shutdown();
});不强制调用 process.exit()
如果希望 Node.js 等待事件循环自然结束,可以设置 forceExit: false。
gracefulShutdown(server, {
forceExit: false
});HTTP Upgrade / WebSocket
如果服务使用 WebSocket 等 HTTP Upgrade 连接,可以开启 gracefulUpgrades。
gracefulShutdown(server, {
gracefulUpgrades: true,
timeout: 30000
});开启后,已升级连接不会在普通清理阶段被当作空闲 keep-alive 连接销毁;库会等待它们自然关闭,或在达到 timeout 后强制关闭。
更早拒绝新连接
默认情况下,preShutdown 结束后才会进入拒绝新连接状态。如果 preShutdown 可能执行较长时间,可以开启 rejectNewConnectionsOnSignal。
gracefulShutdown(server, {
rejectNewConnectionsOnSignal: true,
preShutdown: async () => {
await drainTraffic();
}
});开启后,收到关闭信号会立即拒绝新连接,然后再执行 preShutdown。
Debug 日志
本项目使用 debug 输出调试日志。设置 DEBUG 环境变量即可开启。
Linux / macOS:
export DEBUG=http-graceful-shutdown
node app.jsWindows:
set DEBUG=http-graceful-shutdown
node app.js也可以在启动命令前直接设置:
DEBUG=http-graceful-shutdown node app.js示例
更多 Express、Koa、Fastify、原生 HTTP、HTTP/2 示例请查看 examples 目录。
运行示例前请按需安装依赖:
npm install debug express koa fastify许可证
本项目使用 MIT License。
