Nestjs 微服务 - 有一个 clientProxy 将消息发布到任何微服务

Sex*_*yMF 6 microservices nestjs

有时,你想说:“我有这个消息,谁能处理它?”
nestjs客户端代理中直接绑定到单个microservice.

因此,举个例子,假设我有以下微服务: CleaningServiceFixingService
上面两个都可以处理消息car,但是只能CleaningService处理消息glass

所以,我想要这样的东西:

this.generalProxy.emit('car', {id: 2});
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我想要2 个不同的 microservices来处理汽车:CleaningServiceFixingService

在这种情况下:

this.generalProxy.emit('glass', {id: 5});
Run Code Online (Sandbox Code Playgroud)

我只想CleaningService处理它。

这怎么可能?我如何创建clientProxy不直接绑定到specific microservice.

Jes*_*ter 11

底层传输层很重要,因为尽管不同传输层前面有一个抽象,但每个底层传输层都具有完全不同的特征和功能。您所讨论的消息传递模式类型很容易使用 RabbitMQ 来完成,因为它具有交换、队列、发布者、订阅者等概念,而基于 TCP 的微服务需要从一个服务到另一个服务的连接。同样,Redis 传输层使用简单的通道,无需必要的底层实现即可支持某些消息散布到多个订阅者以及某些消息直接发送到特定订阅者。

这可能不是最流行的观点,但我已经专业使用 NestJS 超过 3 年了,我可以肯定地说官方微服务包不足以满足大多数实际生产应用程序的需求。它们作为概念证明非常有效,但很快就会因为这些类型的问题而崩溃。

幸运的是,NestJS 以模块和 DI 系统的形式提供了出色的构建块和原语,允许构建更多功能丰富的插件。我专门为 RabbitMQ 创建了一个,以便能够支持您所描述的场景的确切类型。

我强烈建议您查看@golevelup/nestjs-rabbitmq,因为您已经在使用 RabbitMQ ,它可以轻松支持您使用本机 RMQ 概念(如交换和路由密钥)完成的任务。(免责声明:我是作者)。它还允许您管理任意数量的交换和队列(而不是被迫尝试通过单个队列推送所有内容),并且对包括 PubSub 和 RPC 在内的多种消息传递模式提供本机支持。

您只需使用适当的元数据装饰您想要充当微服务消息处理程序的方法,消息传递就会按预期工作。例如:

@Injectable()
export class CleaningService {
  @RabbitSubscribe({
    exchange: 'app',
    routingKey: 'cars',
    queue: 'cleaning-cars',
  })
  public async cleanCar(msg: {}) {
    console.log(`Received message: ${JSON.stringify(msg)}`);
  }

  @RabbitSubscribe({
    exchange: 'app',
    routingKey: 'glass',
    queue: 'cleaning-glass',
  })
  public async cleanGlass(msg: {}) {
    console.log(`Received message: ${JSON.stringify(msg)}`);
  }
}
Run Code Online (Sandbox Code Playgroud)
@Injectable()
export class FixingService {
  @RabbitSubscribe({
    exchange: 'app',
    routingKey: 'cars',
    queue: 'fixing-cars',
  })
  public async fixCar(msg: {}) {
    console.log(`Received message: ${JSON.stringify(msg)}`);
  }
}
Run Code Online (Sandbox Code Playgroud)

通过此设置,清洁服务和修理服务都将向各自的处理程序接收汽车消息(因为它们使用相同的路由密钥),并且只有清洁服务才会接收玻璃消息

发布消息很简单。您只需包含交换和路由密钥,正确的处理程序将根据其配置接收它:

amqpConnection.publish('app', 'cars', { year: 2020, make: 'toyota' });
Run Code Online (Sandbox Code Playgroud)

  • 这太棒了,我实际上一开始就遇到了这个,然后完全忘记了。不过有2个问题。1. 您是否有微服务的示例项目?1. 是否可以投入生产?谢谢! (2认同)
  • @SexyMF 我没有使用此库的示例项目,但该库的项目中有大量的 e2e 测试,这些测试针对您可以引用的实际 RabbitMQ 实例进行测试。它已准备好生产。我已经在几个项目中使用过它,并且它在 Nest 社区中得到了相当广泛的采用 (2认同)