使用 NestJS 队列时关闭 redis 连接
Posted
技术标签:
【中文标题】使用 NestJS 队列时关闭 redis 连接【英文标题】:Close redis connection when using NestJS Queues 【发布时间】:2020-11-08 12:12:05 【问题描述】:我正在尝试在 NestJS 项目中设置 E2E 测试,但是,jest 输出如下所示:
Jest did not exit one second after the test run has completed
经过大量阅读,这是因为有一些资源尚未释放,经过一些调试后,它打开了由ioredis
创建的redis 的开放连接,bull
使用该连接,NestJS 使用它来执行任务队列处理。问题是我在测试代码中没有对连接的引用,那么我该如何关闭它呢?我正在像这样在afterAll
jest 的钩子中拆除 Nest 应用程序:
afterAll(async () =>
await app.close();
);
但它什么也没做,连接仍然存在,并且开玩笑的错误消息仍然存在。我知道我可以将--forceExit
添加到jest
命令中,但这并不能解决任何问题,只是将问题隐藏在地毯下。
【问题讨论】:
解决了这个问题吗?我遇到了同样的问题,在使用--detectOpenhandles
后我意识到ioredis
StandaloneConnector
有一个tcp 连接打开
【参考方案1】:
这花了我一段时间才弄清楚。您需要在 afterAll 挂钩中关闭模块。我可以通过查看 nestJS Bull 存储库中的测试找到这一点。
describe('RedisTest', () =>
let module: TestingModule;
beforeAll(async () =>
module = Test.createTestingModule(
imports: [
BullModule.registerQueueAsync(
name: 'test2',
),
],
);
);
afterAll(async () =>
await module.close();
);
);
https://github.com/nestjs/bull/blob/master/e2e/module.e2e-spec.ts
【讨论】:
【参考方案2】:在几乎陷入抑郁的挣扎之后,我找到了一个对我有用的解决方案。
我正在使用"@nestjs/bull": "^0.3.1"
、"bull": "^3.21.1"
。
由于来自bul 包的队列使用redis,因此尽管模块和应用程序已关闭,但它仍保持连接打开。
await moduleRef.close();
await app.close();
我意识到,当使用--detectOpenHandles
同时依赖leaked-handles
库获取更多信息时,您会在控制台中看到类似这样的内容:
tcp stream
fd: 20,
readable: true,
writable: false,
address: ,
serverAddr: null
tcp handle leaked at one of:
at /media/user/somePartitionName/Workspace/Nest/project-
name/node_modules/ioredis/built/connectors/StandaloneConnector.js:58:45
tcp stream
fd: 22,
readable: true,
writable: true,
address: address: '127.0.0.1', family: 'IPv4', port: 34876 ,
serverAddr: null
解决方案
使用beforEach()
& afterEach()
beforEach()
中,添加此指令以获取队列实例:
queue = moduleRef.get(getQueueToken("queuename"));
在afterEach()
中,像这样关闭队列:(同时关闭您的应用和模块以便更好地练习)
await queue.close();
注意
使用
beforAll()
和afterAll()
不起作用,并且发生同样的问题,至少从我尝试过的情况来看,beforEach()
和afterEach()
结合使用。
【讨论】:
现在的问题是,您正在为每个测试分配和关闭连接,似乎您泄漏了连接或代码效率低下(泄漏周期),谢天谢地,我没有接触 nodejs再次(我知道不是nodejs的错,但仍然如此)。以上是关于使用 NestJS 队列时关闭 redis 连接的主要内容,如果未能解决你的问题,请参考以下文章
如何将@liaoliaots/nestjs-redis redis 连接传递给全局保护构造函数
使用 TypeORM 和 NestJs 和 Typescript 创建新迁移时出错 [关闭]