Параметр noAck не работает в микросервисе NestJS RabbitMQ - PullRequest
0 голосов
/ 24 октября 2019

Я использую стратегию ServerRMQ для создания микросервиса в приложении NestJS. Я установил для поля noAck значение false в параметрах сервера:

const app = await NestFactory.createMicroservice(ApplicationModule, {
  strategy: new ServerRMQ({
    urls: [RABBITMQ_URI],
    queue: EXAMPLE_QUEUE_NAME,
    noAck: false,
    queueOptions: {durable: false},
  }),
});

await app.listenAsync();

Когда во время обработки события возникает ошибка, я вызываю метод channel.nack для отправки сообщения not acknowledge в RMQ. После этого RMQ должен отправить сообщение:

@EventPattern(ExampleMessagePattern.EVENT)
  handleExampleEvent(
    @Payload() {meta, payload}: IExampleEventData,
    @Ctx() context: RmqContext,
  ) {
    try{
      ...    // Performing some actions
    } catch(err) {
      const message = context.getMesssage();
      const channel = context.getChannelRef();
      channel.nack(message, false, true);
      // or: context.args[1].nack(context.args[0], false, true);
    }
  }

ER: приложение создает получателя с включенной функцией Acknowledgement required, и метод nack может быть успешно вызван на объекте channel для выполнения механизма повторных попыток, когдапроизошла ошибка.

AR: потребитель создан без функции подтверждения;channel.nack вызов метода приводит к ошибке на стороне RMQ и отключению службы от сервера RMQ.

Ошибка от выхода RabbitMQ:

Ошибка: канал закрыт сервером: 406 (PRECONDITION-FAILED) с сообщением "PRECONDITION_FAILED - неизвестный тег доставки 1

У меня есть предположение, что поле noAck не включает функцию acknowledgement. Чтобы проверить это, я запустил скрипт на python, используя pika библиотека и создал получателя с полем auto_ack, установленным в false:

#!/usr/bin/env python
import pika

credentials = pika.PlainCredentials('rabbit', 'rabbit')
connection = pika.BlockingConnection(
    pika.ConnectionParameters(host='localhost', credentials=credentials))
channel = connection.channel()

channel.queue_declare(queue='example')


def callback(ch, method, properties, body):
    print(" [x] Received %r" % body)


channel.basic_consume(
    queue='example', on_message_callback=callback, auto_ack=False)

print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming() 

Этот сценарий создал получателя, у которого включена функция ack:

enter image description here

На скриншоте вы можете увидеть список потребителей в RabbitMQ Management UI. Первый - это потребитель скрипта Python, для которого Ack required установлен в значение true. Второй - это потребитель NestJS ServerRMQ с noAck установлено в false (но функция ack не включается). Я получил тот же результат, когда попытался установить для noAck значение true (это поведение по умолчанию в ServerRMQ).

Кто-нибудь сталкивался с такой проблемойлем раньше? Это связано с реализацией NestJS ServerRMQ, или я что-то пропустил?

...