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

时间:2020-10-05 05:59:17

标签: microservices nestjs

有时候,您想说:“我有这条消息,谁可以处理?”
nestjs中,客户端代理直接绑定到单个microservice

因此,举例来说,我有以下微服务: CleaningServiceFixingService
上面的两种方法都可以处理消息car,但是只有CleaningService可以处理消息glass

所以,我想要类似的东西:

this.generalProxy.emit('car', {id: 2});

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

在这种情况下:

this.generalProxy.emit('glass', {id: 5});

我只希望CleaningService来处理它。

那怎么可能?如何创建未直接绑定到clientProxy specific的{​​{1}}。

1 个答案:

答案 0 :(得分:2)

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

这可能不是最受欢迎的观点,但是我已经使用NestJS超过3年了,我可以肯定地说,官方的微服务包不足以用于大多数实际生产应用程序。它们可以很好地用作概念证明,但是由于正是这些类型的问题,它们很快就崩溃了。

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

我强烈建议您既然已经在使用RabbitMQ,那么请签出@golevelup/nestjs-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)}`);
  }
}
@Injectable()
export class FixingService {
  @RabbitSubscribe({
    exchange: 'app',
    routingKey: 'cars',
    queue: 'fixing-cars',
  })
  public async fixCar(msg: {}) {
    console.log(`Received message: ${JSON.stringify(msg)}`);
  }
}

通过此设置,清洁服务和固定服务都将向其各自的处理人员接收汽车消息(因为他们使用相同的路由密钥),只有清洁服务将接收玻璃消息

Publishing message is simple。您只需包含交换和路由密钥,正确的处理程序将根据其配置来接收它:

amqpConnection.publish('app', 'cars', { year: 2020, make: 'toyota' });