Я использую стратегию 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](https://i.stack.imgur.com/mQoeq.png)
На скриншоте вы можете увидеть список потребителей в RabbitMQ Management UI
. Первый - это потребитель скрипта Python, для которого Ack required
установлен в значение true. Второй - это потребитель NestJS ServerRMQ с noAck
установлено в false (но функция ack
не включается). Я получил тот же результат, когда попытался установить для noAck
значение true (это поведение по умолчанию в ServerRMQ
).
Кто-нибудь сталкивался с такой проблемойлем раньше? Это связано с реализацией NestJS ServerRMQ
, или я что-то пропустил?