import { Injectable, Logger, OnApplicationShutdown, OnModuleInit, } from "@nestjs/common"; import { closeDb } from "../../config/database.js"; import { closeRedis } from "../../config/redis.js"; import { disconnectKafkaProducer } from "../../config/kafka.js"; const SERVICE_NAME = "config-service"; /** * 优雅停机服务。 * * 关闭顺序: * 1. HTTP/gRPC server 已由 NestJS app.close() 停止 * 2. Kafka producer 断开 * 3. Redis 断开 * 4. DB 连接池关闭(最后关闭) * * v2.1 ADR-032:outbox 投递由 Debezium CDC 接管,本服务不持有 OutboxPublisher。 */ @Injectable() export class LifecycleService implements OnModuleInit, OnApplicationShutdown { private readonly logger = new Logger(LifecycleService.name); onModuleInit(): void { this.logger.log(`service ${SERVICE_NAME} module initialized`); } async onApplicationShutdown(signal?: string): Promise { this.logger.log( `service ${SERVICE_NAME} shutting down (signal=${signal ?? "unknown"})`, ); // 1. Kafka producer try { await disconnectKafkaProducer(); this.logger.log("Kafka producer disconnected"); } catch (error) { this.logger.error( `Kafka producer disconnect failed: ${error instanceof Error ? error.message : String(error)}`, ); } // 2. Redis try { await closeRedis(); this.logger.log("Redis connection closed"); } catch (error) { this.logger.error( `Redis close failed: ${error instanceof Error ? error.message : String(error)}`, ); } // 3. DB(最后关闭) try { await closeDb(); this.logger.log("database connection closed"); } catch (error) { this.logger.error( `database close failed: ${error instanceof Error ? error.message : String(error)}`, ); } this.logger.log(`service ${SERVICE_NAME} shutdown complete`); } }