如何基于nestjs-ioredis在NestJS中创建额外Redis客户端连接
实现步骤
1. 模块注册阶段配置双独立连接
你使用的nestjs-ioredis本身支持通过名称注册多个独立的Redis连接实例,不需要手动实例化连接,只要在Nest模块导入时为每个连接配置唯一标识,指向同一个Redis数据库地址,就能实现原生代码里两个独立实例化连接的效果。
在应用根模块(或对应功能模块)中导入模块时,分别注册两个连接:
import { Module } from '@nestjs/common'; import { IoredisModule } from 'nestjs-ioredis'; @Module({ imports: [ // 第一个连接:专属用作订阅者,对应原生代码里执行subscribe操作的实例 IoredisModule.forRoot({ name: 'subscriber', // 下方配置和你之前单连接的配置完全一致 host: '你的Redis服务地址', port: 你的Redis端口号, password: '你的Redis访问密码(如有)', db: 0, // 你的目标数据库索引 }), // 第二个连接:专属用作发布者,对应原生代码里执行publish操作的pub实例 IoredisModule.forRoot({ name: 'publisher', // 配置和订阅者连接完全一致,确保指向同一个数据库 host: '你的Redis服务地址', port: 你的Redis端口号, password: '你的Redis访问密码(如有)', db: 0, }), ], }) export class AppModule {}
2. 业务代码中注入连接实现发布订阅逻辑
通过@InjectConnection()装饰器传入对应连接的名称,就能拿到和原生ioredis完全一致的客户端实例,所有API调用方式和你贴的原生Node代码没有区别。
编写对应的服务类处理订阅逻辑:
import { Injectable, OnModuleInit } from '@nestjs/common'; import { InjectConnection } from 'nestjs-ioredis'; import Redis from 'ioredis'; @Injectable() export class RedisPubSubService implements OnModuleInit { constructor( // 注入专属的订阅者连接 @InjectConnection('subscriber') private readonly subscriber: Redis, // 注入专属的发布者连接 @InjectConnection('publisher') private readonly publisher: Redis, ) {} // 模块初始化完成后执行订阅逻辑 async onModuleInit() { // 执行频道订阅,逻辑和原生代码完全对齐 await this.subscriber.subscribe('news', 'music', (err, count) => { if (err) { console.error('频道订阅失败:', err); return; } // 订阅成功后通过发布者连接发送测试消息 this.publisher.publish('news', 'Hello world!'); this.publisher.publish('music', 'Hello again!'); }); // 绑定普通消息监听事件 this.subscriber.on('message', (channel, message) => { console.log('Receive message %s from channel %s', message, channel); }); // 绑定Buffer类型的消息监听事件 this.subscriber.on('messageBuffer', (channel, message) => { // 此处获取的channel和message均为Buffer类型,按需处理即可 }); } // 可封装通用发布方法,供其他业务模块调用 async sendMessage(channel: string, content: string) { await this.publisher.publish(channel, content); } }
注意事项
- 千万别图省事用同一个连接同时做订阅和发布:ioredis本身的机制是,连接一旦执行
subscribe操作就会进入专属订阅模式,再去执行publish、缓存读写这类普通命令会直接报错,这也是原生代码里要新建两个独立连接的原因。 - 两个连接的配置必须完全对齐:host、端口、密码、数据库索引这些参数要一模一样,确保都指向同一个Redis实例和数据库,不然会出现订阅了但收不到同库发布的消息的问题。
- 每个注册的连接必须有唯一的
name标识:如果两个连接重名,Nest的依赖注入容器会直接覆盖之前注册的实例,最后拿到的其实是同一个连接,达不到双连接的目的。
内容的提问来源于stack exchange,提问作者Doddle
相关产品推荐
相关产品推荐

