NATS NATS

导读

NATS 是一个简单、安全且高性能的开源消息传递系统,适用于云原生应用程序、物联网消息传递和微服务架构。NATS 服务器使用 Go 编程语言编写,但用于与服务器交互的客户端库可用于数十种主要编程语言。NATS 支持 最多一次至少一次 交付。它可以在任何地方运行,从大型服务器和云实例,到边缘网关,甚至物联网设备。

安装

要开始构建基于 NATS 的微服务,首先安装所需的包:

bash
$ npm i --save nats

概述

要使用 NATS 传输器,请将以下选项对象传递给 createMicroservice() 方法:

main
ts
const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.NATS,
  options: {
    servers: ['nats://localhost:4222'],
  },
})
js
const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.NATS,
  options: {
    servers: ['nats://localhost:4222'],
  },
})
提示

Transport 枚举从 @nestjs/microservices 包导入。

选项

options 对象特定于所选传输器。NATS 传输器公开了 此处 描述的属性。 此外,还有一个 queue 属性,允许您指定服务器应订阅的队列的名称(保留 undefined 以忽略此设置)。阅读有关 下面 的 NATS 队列组的更多信息。

客户端

与其他微服务传输器一样,您有 几个选项 用于创建 NATS ClientProxy 实例。

创建实例的一种方法是使用ClientsModule。要使用ClientsModule创建客户端实例,请导入它并使用register()方法传递一个选项对象,该对象具有与createMicroservice()方法中上面显示的属性相同的属性,以及一个用作注入令牌的name属性。在此处阅读有关ClientsModule的更多信息。

ts
@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'MATH_SERVICE',
        transport: Transport.NATS,
        options: {
          servers: ['nats://localhost:4222'],
        }
      },
    ]),
  ]
})

还可以使用其他选项来创建客户端(ClientProxyFactory@Client())。您可以在 此处 阅读有关它们的信息。

请求-响应

对于 请求-响应 消息样式(阅读更多),NATS 传输器不使用 NATS 内置的 请求-回复 机制。相反,使用 publish() 方法在给定主题上发布具有唯一回复主题名称的请求,响应者监听该主题并向回复主题发送响应。回复主题会动态地定向回请求者,无论任何一方的位置如何。

基于事件

对于 基于事件 的消息样式(阅读更多),NATS 传输器使用 NATS 内置的 发布-订阅 机制。发布者发送有关某个主题的消息,任何正在监听该主题的活动订阅者都会收到该消息。订阅者还可以注册对通配符主题的兴趣,其工作方式有点像正则表达式。这种一对多模式有时称为扇出。

队列组

NATS 提供了一个名为 分布式队列 的内置负载平衡功能。要创建队列订阅,请使用 queue 属性,如下所示:

main
ts
const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.NATS,
  options: {
    servers: ['nats://localhost:4222'],
    queue: 'cats_queue',
  },
})

上下文

在更复杂的场景中,您可能希望访问有关传入请求的更多信息。使用 NATS 传输器时,您可以访问NatsContext对象。

ts
TS
ts
@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: NatsContext) {
  console.log(`Subject: ${context.getSubject()}`);
}
提示

@Payload()@Ctx()NatsContext@nestjs/microservices 包导入。

通配符

订阅可能针对明确主题,也可能包含通配符。

ts
TS
ts
@MessagePattern('time.us.*')
getDate(@Payload() data: number[], @Ctx() context: NatsContext) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}

记录构建器

要配置消息选项,您可以使用 NatsRecordBuilder 类(注意:这也适用于基于事件的流)。例如,要添加 x-version 标头,请使用 setHeaders 方法,如下所示:

ts
import * as nats from 'nats';

// somewhere in your code
const headers = nats.headers();
headers.set('x-version', '1.0.0');

const record = new NatsRecordBuilder(':cat:').setHeaders(headers).build();
this.client.send('replace-emoji', record).subscribe(...);
提示

NatsRecordBuilder 类从 @nestjs/microservices 包中导出。

您也可以通过访问 NatsContext 在服务器端读取这些标头,如下所示:

ts
TS
ts
@MessagePattern('replace-emoji')
replaceEmoji(@Payload() data: string, @Ctx() context: NatsContext): string {
  const headers = context.getHeaders();
  return headers['x-version'] === '1.0.0' ? '🐱' : '🐈';
}

在某些情况下,您可能需要为多个请求配置标头,您可以将这些标头作为选项传递给ClientProxyFactory

ts
import { Module } from '@nestjs/common'
import { ClientProxyFactory, Transport } from '@nestjs/microservices'

@Module({
  providers: [
    {
      provide: 'API_v1',
      useFactory: () =>
        ClientProxyFactory.create({
          transport: Transport.NATS,
          options: {
            servers: ['nats://localhost:4222'],
            headers: { 'x-version': '1.0.0' },
          },
        }),
    },
  ],
})
export class ApiModule {}