Redis 传输器
Redis
Redis 传输器实现了发布/订阅消息传递范式,并利用了 Redis 的 Pub/Sub 功能。发布的消息被分类到通道中,而不知道哪些订阅者(如果有的话)最终会接收到消息。每个微服务可以订阅任意数量的通道。此外,可以同时订阅多个通道。通过通道交换的消息是即发即忘的,这意味着如果发布了一条消息而没有订阅者对其感兴趣,该消息将被删除且无法恢复。因此,您无法保证消息或事件至少会被一个服务处理。单个消息可以被多个订阅者订阅(和接收)。

安装
要开始构建基于 Redis 的微服务,首先安装所需的包:
$ npm i --save ioredis
概述
要使用 Redis 传输器,请将以下选项对象传递给 createMicroservice() 方法:
@@filename(main)
const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
transport: Transport.REDIS,
options: {
host: 'localhost',
port: 6379,
},
});
@@switch
const app = await NestFactory.createMicroservice(AppModule, {
transport: Transport.REDIS,
options: {
host: 'localhost',
port: 6379,
},
});
提示 Transport 枚举从 @nestjs/microservices 包导入。
选项
options 属性特定于所选的传输器。Redis 传输器公开以下属性。
| 属性 | 描述 |
|---|---|
host | 连接 URL |
port | 连接端口 |
retryAttempts | 消息重试次数(默认:0) |
retryDelay | 消息重试尝试之间的延迟(毫秒)(默认:0) |
wildcards | 启用 Redis 通配符订阅,指示传输器在底层使用 psubscribe/pmessage(默认:false) |
官方 ioredis 客户端支持的所有属性也被此传输器支持。
客户端
与其他微服务传输器一样,您有几种选项来创建 Redis ClientProxy 实例。
创建实例的一种方法是使用 ClientsModule。要使用 ClientsModule 创建客户端实例,请导入它并使用 register() 方法传递一个选项对象,该对象具有与上面 createMicroservice() 方法中显示的相同属性,以及一个用作注入令牌的 name 属性。在此处了解更多关于 ClientsModule 的信息。
@Module({
imports: [
ClientsModule.register([
{
name: 'MATH_SERVICE',
transport: Transport.REDIS,
options: {
host: 'localhost',
port: 6379,
}
},
]),
]
...
})
创建客户端的其他选项(ClientProxyFactory 或 @Client())也可以使用。您可以在此处了解它们。
上下文
在更复杂的场景中,您可能需要访问有关传入请求的其他信息。当使用 Redis 传输器时,您可以访问 RedisContext 对象。
@@filename()
@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RedisContext) {
console.log(`Channel: ${context.getChannel()}`);
}
@@switch
@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
console.log(`Channel: ${context.getChannel()}`);
}
提示 @Payload()、@Ctx() 和 RedisContext 从 @nestjs/microservices 包导入。
通配符
要启用通配符支持,请将 wildcards 选项设置为 true。这指示传输器在底层使用 psubscribe 和 pmessage。
const app = await NestFactory.createMicroservice(AppModule, {
transport: Transport.REDIS,
options: {
// 其他选项
wildcards: true,
},
});
在创建客户端实例时也要确保传递 wildcards 选项。
启用此选项后,您可以在消息和事件模式中使用通配符。例如,要订阅所有以 notifications 开头的通道,您可以使用以下模式:
@EventPattern('notifications.*')
实例状态更新
要获取连接和底层驱动程序实例状态的实时更新,您可以订阅 status 流。此流提供特定于所选驱动程序的状态更新。对于 Redis 驱动程序,status 流会发出 connected、disconnected 和 reconnecting 事件。
this.client.status.subscribe((status: RedisStatus) => {
console.log(status);
});
提示 RedisStatus 类型从 @nestjs/microservices 包导入。
同样,您可以订阅服务器的 status 流以接收有关服务器状态的通知。
const server = app.connectMicroservice<MicroserviceOptions>(...);
server.status.subscribe((status: RedisStatus) => {
console.log(status);
});
监听 Redis 事件
在某些情况下,您可能想要监听微服务发出的内部事件。例如,您可以监听 error 事件以在发生错误时触发其他操作。为此,请使用 on() 方法,如下所示:
this.client.on('error', (err) => {
console.error(err);
});
同样,您可以监听服务器的内部事件:
server.on<RedisEvents>('error', (err) => {
console.error(err);
});
提示 RedisEvents 类型从 @nestjs/microservices 包导入。
底层驱动程序访问
对于更高级的用例,您可能需要访问底层驱动程序实例。这对于手动关闭连接或使用特定于驱动程序的方法等场景很有用。但是,请记住,在大多数情况下,您不应该需要直接访问驱动程序。
为此,您可以使用 unwrap() 方法,该方法返回底层驱动程序实例。泛型类型参数应指定您期望的驱动程序实例类型。
const [pub, sub] =
this.client.unwrap<[import('ioredis').Redis, import('ioredis').Redis]>();
同样,您可以访问服务器的底层驱动程序实例:
const [pub, sub] =
server.unwrap<[import('ioredis').Redis, import('ioredis').Redis]>();
请注意,与其他传输器相反,Redis 传输器返回两个 ioredis 实例的元组:第一个用于发布消息,第二个用于订阅消息。