问题描述
我想在消费时结束订阅队列。
但是我的ack模式是AckNowledgeMode.AUTO,容器会根据监听器是正常返回还是抛出异常来发出ack/nack。
所以,如果我在消耗方法中取消订阅,然后该方法返回,并且容器尝试确认,但它之前已经取消订阅,那么会发生什么,这样做是否安全,如下所示:
退订方式一
DirectMessageListenerContainer container = getContainer();
container.setMessageListener(message -> {
// do something with message
// if some condition reaches,unsubscribe
if (reachEnd()) {
container.removeQueueNames(message.getMessageProperties().getConsumerQueue());
}
});
退订方式2
container.setMessageListener(new ChannelAwareMessageListener() {
@Override
public void onMessage(Message message,Channel channel) throws Exception {
// do something with message
// if some condition reaches,unsubscribe
if (reachEnd()) {
channel.basicCancel(message.getMessageProperties().getConsumerTag());
}
}
});
解决方法
我两者都不做,而是停止容器。无论哪种方式都会导致消费者被取消。
您应该在新线程上调用 stop(),而不是在侦听器线程上调用 - 这会导致死锁。