Issue
@EnableRabbit
@Service
public class RabbitMqListenerWithReply {
@Autowired
RabbitTemplate rabbitTemplate;
@Value("${test.rabbitmq.exchange}")
private String rabbitMQExchange;
@Value("${test.rabbitmq.routingkey}")
private String rabbitMQRoutingKey;
@RabbitListener(queues = "${test.rabbitmq.queue}")
public void receiveMessage(String message, Channel channel,
@Header(AmqpHeaders.DELIVERY_TAG)long tag) throws IOException {
System.out.println(message.toString());
channel.basicAck(tag, false);
System.out.println("Ackd");
}
}
I am trying to implement a listener which acknowledge the message after I consume it, however the console would return this error so can someone guide me on where I could have went wrong.
This is the error that I am getting right now whenever I run the publisher to publish the message to the exchange.
2022-01-03 09:35:33.192 ERROR 27280 --- [ 127.0.0.1:5672] o.s.a.r.c.CachingConnectionFactory : Channel shutdown: channel error; protocol method: #method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - unknown delivery tag 1, class-id=60, method-id=80)
2022-01-03 09:35:34.208 INFO 27280 --- [ntContainer#0-1] o.s.a.r.l.SimpleMessageListenerContainer : Restarting Consumer@52d7ab79: tags=[[amq.ctag-0pIM_-TROTIxXRsAJpmOrw]], channel=Cached Rabbit Channel: AMQChannel(amqp://[email protected]:5672/,1), conn: Proxy@71369e1a Shared Rabbit Connection: SimpleConnection@60b616c8 [delegate=amqp://[email protected]:5672/, localPort= 57660], acknowledgeMode=AUTO local queue size=0
This is how I am publishing my message at the moment.
@RestController
@RequestMapping("api/test")
public class RestAPIController {
@Autowired
RabbitTemplate rabbitTemplate;
@Value("${test.rabbitmq.exchange}")
private String rabbitMQExchange;
@Value("${test.rabbitmq.routingkey}")
private String rabbitMQRoutingKey;
@Value("${test.rabbitmq.queue}")
private String rabbitMQQueue;
@GetMapping("{message}")
public String testAPI(@PathVariable("message") String message) {
System.out.println("Message sent: " + message);
rabbitTemplate.convertAndSend(rabbitMQExchange, rabbitMQRoutingKey , message);
return "The message was sent";
}
}
Solution
@RabbitListener
use AUTO-ACK by default.
The container acknowledges the message automatically, unless the MessageListener throws an exception.
So if you ack once in listener
, the framework will ack once, and repeating ack causes this exception.
Try:
@RabbitListener(queues = "xxx", ackMode = "MANUAL")
Answered By - zysaaa
Answer Checked By - David Marino (JavaFixing Volunteer)