shutdown-check 1.0.1 可在 macOS 和 Linux 上运行,需要 Node.js 22 或更高版本。它面向的是服务进程和端口,不需要导入框架代码,因此可以测试任何本地 HTTP/1 服务。
支持矩阵
| 方面 | 支持情况 |
|---|---|
| Node.js | 22 或更高版本 |
| 操作系统 | macOS 和 Linux |
| 模块系统 | ESM 和 CommonJS |
| TypeScript | 两个模块入口都提供类型声明 |
| 框架 | node:http、Express、Fastify、NestJS 及其他 HTTP/1 框架 |
| 协议 | 本地明文 HTTP/1 |
| 主机 | localhost、127.0.0.1 和 [::1] |
| 关闭信号 | SIGTERM |
| 报告 | 文本、JSON 和 JUnit XML |
| 运行时依赖 | 无 |
| 许可证 | MIT |
Node.js 版本
运行 shutdown-check 的机器需要 Node.js 22 或更高版本。工具用到了较新的 Node.js API,并在包的元数据中声明了这一要求。
服务由你配置的启动命令启动。实际使用中,服务通常和检查用的是同一个 Node.js 安装,所以 CI 示例都会显式指定 Node.js 22。
操作系统
只支持 macOS 和 Linux。shutdown-check 依赖以下 POSIX 行为:
- 投递
SIGTERM - 分离(detached)的进程组
- 清理时向整个进程组发送信号
- 本地 TCP 连接的行为
Windows 没有同样的信号和进程组模型。请在 WSL、Linux 容器或 Linux CI runner 中运行测试,不要直接在原生 Windows 上运行。
HTTP 与网络限制
baseUrl 必须使用明文 HTTP 和回环地址:
http://localhost:3000
http://127.0.0.1:3000
http://[::1]:3000工具不会连接远程主机。baseUrl 中也不能包含凭据、查询字符串、片段(fragment)或路径。路径请写在 readiness、workload、探测路由和新请求相关的字段里。
以下内容目前不在协议支持范围内:
- HTTPS 和 TLS 终止
- HTTP/2 流
- WebSocket 连接
- Unix socket
- 远程预发布环境或生产环境的 URL
如果服务前面有反向代理,请测试代理后面的本地 HTTP 服务器,而不是代理本身。
框架兼容性
shutdown-check 没有针对框架的适配器。只要服务能通过命令启动、监听本地 HTTP,并且处理 SIGTERM,就可以测试。
关闭行为仍然由框架决定。例如:
- node:http 和 Express 使用底层的
server.close() - Fastify 提供
fastify.close() - NestJS 需要启用关闭钩子(shutdown hooks),并等待其执行完成
- 自定义框架必须自己停止接收新工作并关闭资源
node:http、Express 和 Fastify 的示例见 Node.js 优雅关闭指南。
模块支持
包提供 ESM 和 CommonJS 两个入口,都带有 TypeScript 类型。
import { checkShutdown } from "shutdown-check";const { checkShutdown } = require("shutdown-check");CommonJS 支持和 --version 参数是在 1.0.1 中加入的。
信号支持
只接受 SIGTERM。Linux 进程管理器、容器运行时和 Kubernetes 在正常优雅停止时发送的都是这个信号。
不支持 SIGINT、自定义信号和 Windows 控制台事件。如果配置里写了其他信号,测试开始前就会被拒绝。
可选的 repeatSignalAfterMs 会再发送一次 SIGTERM,但不会改变信号类型。
测试能验证什么
工具可以直接观察到:
- 服务是否启动并进入就绪状态
- 发送信号前是否有请求正在进行
- 进行中的响应是否以预期的状态码和响应体完成
- 就绪状态是否发生变化
- 新的 HTTP 请求是否被拒绝
- 进程是否以预期的退出码、在截止时间内退出
- HTTP 端口是否关闭
- 包装进程是否留下仍在运行的子服务器
测试无法直接看到什么
HTTP 响应并不能反映所有内部操作。shutdown-check 不会直接验证:
- 响应之后的数据库事务
- 队列消息的确认(ack)
- 后台任务
- 文件落盘(flush)
- 外部服务的清理
- WebSocket 或 HTTP/2 会话的排空
- 容器端点的移除
- 负载均衡器侧的更新传播
- Kubernetes 的
preStop钩子
如果响应本身能证明工作成功完成,就使用 workload.bodyIncludes。对于响应之后还在继续的工作,请补充针对应用的集成测试。
容器支持
满足以下条件时,可以在 Linux 容器内运行测试:
- 安装了 Node.js 22 或更高版本
- 容器内可以获取到这个包
- 可以创建子进程并向其发送信号
- 服务在同一个容器内绑定回环地址上的端口
这样测的是镜像里的服务器,但测不到 Kubernetes 端点更新、preStop 和集群的宽限期(grace period)。这些请在预发布环境的集群中单独测试。参见 Kubernetes 与容器。
资源与安全限制
workload.concurrent支持 1 到 20 个请求。- 响应体最多捕获 1 MiB。
- 服务的 stdout 和 stderr 只保留最后 8 KiB。
- 所有超时都有文档说明的取值范围,上限为 300000 ms。
- 所有请求路径都必须在配置的本地源(origin)之内。
- 运行失败时,清理阶段会强制杀掉进程组。
不要让测试请求触发生产环境中的破坏性操作。视情况使用隔离的测试数据和仅供测试的路由。