| 生命周期钩子方法 | 触发时机 | 用途 | 示例场景 |
|---|---|---|---|
| onModuleInit() | 模块初始化完成时 | 模块级设置或初始化任务,如建立数据库连接 | MongoDB 数据库连接初始化 |
| onApplicationBootstrap() | 所有模块初始化后,在侦听连接前 | 跨模块或全局执行的初始化任务,如启动日志服务 | 与支付网关的连接建立和外部服务的可用性检查 |
| onModuleDestroy() | 收到终止信号后 | 模块销毁时的清理逻辑,如关闭数据库连接 | 模块资源清理,如关闭数据库连接 |
| beforeApplicationShutdown() | 主动调用 app.close() 或接收到系统终止信号时 | 应用程序关闭前的整体清理和资源释放 | 保存状态,关闭外部服务连接,发送关闭通知 |
| onApplicationShutdown() | 应用程序即将完全关闭时 | 应用程序关闭流程的最后阶段执行最终清理操作 | 资源释放,停止后台进程,清理缓存,记录日志 |
app.js
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// 加入这个
// Starts listening for shutdown hooks
app.enableShutdownHooks();
await app.listen(3000);
}
bootstrap();
@Injectable()
// 实现上述生命周期中的方法,不同生命周期有不同的适用场景
class UsersService implements OnApplicationShutdown {
onApplicationShutdown(signal: string) {
console.log(signal); // e.g. "SIGINT"
}
}
OnModuleDestroy, BeforeApplicationShutdown 用 while true 卡主,没一会就 gc 了; 注意里面要加 sleep
^C
<--- Last few GCs --->
[30626:0x118040000] 52296 ms: Scavenge (reduce) 4037.4 (4109.9) -> 4037.3 (4111.7) MB, 5.0 / 0.0 ms (average mu = 0.283, current mu = 0.227) allocation failure;
[30626:0x118040000] 52315 ms: Scavenge (reduce) 4042.3 (4114.9) -> 4042.2 (4116.9) MB, 9.2 / 0.0 ms (average mu = 0.283, current mu = 0.227) allocation failure;
[30626:0x118040000] 52327 ms: Scavenge (reduce) 4047.9 (4120.7) -> 4048.0 (4122.2) MB, 5.2 / 0.0 ms (average mu = 0.283, current mu = 0.227) allocation failure;
<--- JS stacktrace --->
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
1: 0x1024a26e4 node::Abort() [/Users/***/.nvm/versions/node/v18.17.0/bin/node]
2: 0x1024a28c8 node::ModifyCodeGenerationFromStrings(v8::Local<v8::Context>, v8::Local<v8::Value>, bool) [/Users/***/.nvm/versions/node/v18.17.0/bin/node]
3: 0x1025f960c v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [/Users/***/.nvm/versions/node/v18.17.0/bin/node]
4: 0x1027a3ec4 v8::internal::EmbedderStackStateScope::EmbedderStackStateScope(v8::internal::Heap*, v8::internal::EmbedderStackStateScope::Origin, cppgc::EmbedderStackState) [/Users/***/.nvm/versions/node/v18.17.0/bin/node]
5: 0x1027a7ab0 v8::internal::Heap::CollectSharedGarbage(v8::internal::GarbageCollectionReason) [/Users/***/.nvm/versions/node/v18.17.0/bin/node]
6: 0x1027a4ac4 v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::internal::GarbageCollectionReason, char const*, v8::GCCallbackFlags) [/Users/***/.nvm/versions/node/v18.17.0/bin/node]
7: 0x1027a1dc4 v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [/Users/***/.nvm/versions/node/v18.17.0/bin/node]
8: 0x1027a0eec v8::internal::Heap::HandleGCRequest() [/Users/***/.nvm/versions/node/v18.17.0/bin/node]
9: 0x10274e494 v8::internal::StackGuard::HandleInterrupts() [/Users/***/.nvm/versions/node/v18.17.0/bin/node]
10: 0x102b1cfd0 v8::internal::Runtime_StackGuard(int, unsigned long*, v8::internal::Isolate*) [/Users/***/.nvm/versions/node/v18.17.0/bin/node]
11: 0x102e6d04c Builtins_CEntry_Return1_DontSaveFPRegs_ArgvOnStack_NoBuiltinExit [/Users/***/.nvm/versions/node/v18.17.0/bin/node]
12: 0x1080d0d64
13: 0x102df8198 Builtins_InterpreterEntryTrampoline [/Users/***/.nvm/versions/node/v18.17.0/bin/node]
14: 0x108030350
15: 0x1080304a4
16: 0x102e82ffc Builtins_ArrayFrom [/Users/***/.nvm/versions/node/v18.17.0/bin/node]
17: 0x10803b6c4
18: 0x1080b8fd8
19: 0x1080b83dc
20: 0x102df8198 Builtins_InterpreterEntryTrampoline [/Users/***/.nvm/versions/node/v18.17.0/bin/node]
21: 0x102e29ef4 Builtins_AsyncFunctionAwaitResolveClosure [/Users/***/.nvm/versions/node/v18.17.0/bin/node]
22: 0x102eb8738 Builtins_PromiseFulfillReactionJob [/Users/***/.nvm/versions/node/v18.17.0/bin/node]
23: 0x102e1bc4c Builtins_RunMicrotasks [/Users/***/.nvm/versions/node/v18.17.0/bin/node]
24: 0x102df63a4 Builtins_JSRunMicrotasksEntry [/Users/***/.nvm/versions/node/v18.17.0/bin/node]
25: 0x102725d10 v8::internal::(anonymous namespace)::Invoke(v8::internal::Isolate*, v8::internal::(anonymous namespace)::InvokeParams const&) [/Users/***/.nvm/versions/node/v18.17.0/bin/node]
26: 0x102726200 v8::internal::(anonymous namespace)::InvokeWithTryCatch(v8::internal::Isolate*, v8::internal::(anonymous namespace)::InvokeParams const&) [/Users/***/.nvm/versions/node/v18.17.0/bin/node]
27: 0x1027263dc v8::internal::Execution::TryRunMicrotasks(v8::internal::Isolate*, v8::internal::MicrotaskQueue*, v8::internal::MaybeHandle<v8::internal::Object>*) [/Users/***/.nvm/versions/node/v18.17.0/bin/node]
28: 0x10274cb44 v8::internal::MicrotaskQueue::RunMicrotasks(v8::internal::Isolate*) [/Users/***/.nvm/versions/node/v18.17.0/bin/node]
29: 0x10274d2e0 v8::internal::MicrotaskQueue::PerformCheckpoint(v8::Isolate*) [/Users/***/.nvm/versions/node/v18.17.0/bin/node]
30: 0x1023e8c4c node::InternalCallbackScope::Close() [/Users/***/.nvm/versions/node/v18.17.0/bin/node]
31: 0x1023e8fd0 node::InternalMakeCallback(node::Environment*, v8::Local<v8::Object>, v8::Local<v8::Object>, v8::Local<v8::Function>, int, v8::Local<v8::Value>*, node::async_context) [/Users/***/.nvm/versions/node/v18.17.0/bin/node]
32: 0x1023fe36c node::AsyncWrap::MakeCallback(v8::Local<v8::Function>, int, v8::Local<v8::Value>*) [/Users/***/.nvm/versions/node/v18.17.0/bin/node]
33: 0x102552838 node::(anonymous namespace)::SignalWrap::Start(v8::FunctionCallbackInfo<v8::Value> const&)::'lambda'(uv_signal_s*, int)::__invoke(uv_signal_s*, int) [/Users/***/.nvm/versions/node/v18.17.0/bin/node]
34: 0x102ddf608 uv__signal_event [/Users/***/.nvm/versions/node/v18.17.0/bin/node]
35: 0x102de82a8 uv__io_poll [/Users/***/.nvm/versions/node/v18.17.0/bin/node]
36: 0x102dd5e28 uv_run [/Users/***/.nvm/versions/node/v18.17.0/bin/node]
37: 0x1023e96e0 node::SpinEventLoop(node::Environment*) [/Users/***/.nvm/versions/node/v18.17.0/bin/node]
38: 0x1024df2d4 node::NodeMainInstance::Run() [/Users/***/.nvm/versions/node/v18.17.0/bin/node]
39: 0x10246f338 node::LoadSnapshotDataAndRun(node::SnapshotData const**, node::InitializationResult const*) [/Users/***/.nvm/versions/node/v18.17.0/bin/node]
40: 0x10246f5f0 node::Start(int, char**) [/Users/***/.nvm/versions/node/v18.17.0/bin/node]
41: 0x18a90d058 start [/usr/lib/dyld]
[1] 30626 abort node ./dist/src/main.js