【发布时间】:2022-01-10 14:38:55
【问题描述】:
所以,在我深入探讨这个问题之前,让我向您解释一下我的应用的基本原理。
我在我的应用中连接到 DB(TypeOrm)、Kafka(kafkajs)。
我的应用是 1 个主题的消费者,其中:
- 在回调处理程序中获取一些数据,并使用 TypeORM 实体将该数据放入一个表中
- 维护 全局地图(在某个类的一些单例实例中)和一些 id(我在点 1 的数据中得到)。
在应用关闭时,我的任务是:
- 从 Kafka 断开所有主题(此服务连接到)的消费者
- 遍历全球地图(第 2 点)并在某个主题中重新放置消息
- 使用 close 方法断开数据库连接。
这里有一些代码可以帮助你理解我是如何在 NestJs 中的 Server 上添加生命周期事件的。
system.server.life.cycle.events.ts
@Injectable()
export class SystemServerLifeCycleEventsShared implements BeforeApplicationShutdown {
constructor(@Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger, private readonly someService: SomeService) {}
async beforeApplicationShutdown(signal: string) {
const [err] = await this.someService.handleAbruptEnding();
if (err) this.logger.info(`beforeApplicationShutdown, error::: ${JSON.stringify(err)}`);
this.logger.info(`beforeApplicationShutdown, signal ${signal}`);
}
}
some.service.ts
export class SomeService {
constructor(private readonly kafkaConnector: KafkaConnector, private readonly postgresConnector: PostgresConnector) {}
public async handleAbruptEnding(): Promise<any> {
await this.kafkaConnector.disconnectAllConsumers();
for(READ_FROM_GLOBAL_STORE) {
await this.kafkaConnector.function.call.to.repark.the.message();
}
await this.postgresConnector.disconnectAllConnections();
return true;
}
}
postgres.connector.ts
export class PostgresConnector {
private connectionManager: ConnectionManager;
constructor () {
this.connectionManager = getConnectionManager();
}
public async disconnectAllConnections(): Promise<void[]> {
const connectionClosePromises: Promise<void> = [];
connectionManager.connections?.forEach((connection) => {
if (connection.isConnected) connectionClosePromises.push(connection.close());
});
return Promise.all(connectionClosePromises);
}
}
ConnectionManager&getConnectionManager() 从 TypeORM 模块导入。
下面是我面临的一些不寻常的异常/行为:
-
断开所有连接会引发异常/错误,如引用:
错误 [TypeOrmModule] 无法在“默认”连接上执行操作,因为连接尚未建立。 如果连接还没有建立,那么我的 isConnected 怎么会在 if 中实现。我在任何地方都没有任何线索,这怎么可能。以及如何在 TypeORM 中优雅地关闭连接。
-
我们真的需要在 TypeORM 中处理连接的关闭还是它在内部处理它。
-
即使 TypeORM 在内部处理连接闭包,我们如何显式实现它。
-
如果连接正确断开,是否可以触发任何回调,以便我确定断开连接实际上是从数据库发生的。
-
在我按下 CTRL + C(模仿我的服务器进程的突然/关闭)并且控制权返回到终端之后,一些消息会出现。这意味着,在句柄返回到我的终端后,一些线程正在返回(????,不知道,我将如何处理这个,因为如果你看到,我的 handleAbruptHandling 是 awaited 而且,我交叉检查所有承诺都在正确等待。)
需要了解的一些事情:
- 我正确添加了我的模块来创建服务器生命周期事件的挂钩。
- 正确注入了几乎所有类中的对象。
- 没有从 NEST 得到任何 DI 问题并且服务器正在正常启动。
请说明一下,让我知道如何在 NestJs 中使用 typeorm api 优雅地断开与数据库的连接,以防突然关闭。
在此先感谢,祝您编码愉快:)
【问题讨论】: