消息队列,消息队列,消息队列!
Consumer Ack
是指消费端收到消息后的确认方式,常见的有两种确认方式:
自动确认:acknowledge
=“none
”,自动确认是指消息一旦被consumer
接收到,那么则自动确认收到,并将相应的message
从消息队列中移除。这种处理方式不安全,因为消息被接受了但是业务没有处理成功,那么就会造成消息丢失
手动确认:acknowledge
=“manual
”,如果消息被consumer
接收到,就调用channel
的basicAck()
签收;如果没有被接收到,调用basicNack()
拒绝签收,broker
重新发送给consumer
所以在业务中,我们最好选用手动确认的方式,以免发生问题,导致消息丢失。
自动确认:
先设置相应的属性。
package com.thorns.listener;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageListener;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.stereotype.Component;
import java.io.IOException;
@Component
public class AckListener implements ChannelAwareMessageListener {
@Override
public void onMessage(Message message, Channel channel){
System.out.println(new String(message.getBody()));
}
}
手动确认:
也是同样的,需要先设置相应的属性。
package com.thorns.listener;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageListener;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.stereotype.Component;
import java.io.IOException;
/**
* 设置手动签收
* acknowledge="manual"
* 让监听器类实现ChannelAwareMessageListener接口
* 如果消息成功处理,则调用channel的basicAck()签收
* 如果消息处理失败,则调用basicNack()拒绝签收,broker重新发送给consumer
*/
@Component
public class AckListener implements ChannelAwareMessageListener {
@Override
public void onMessage(Message message, Channel channel) throws Exception {
long deliveryTag = message.getMessageProperties().getDeliveryTag();
try {
System.out.println(new String(message.getBody()));
System.out.println("处理业务逻辑");
// 手动设置一个异常
int i = 3/0;
channel.basicAck(deliveryTag,true);
}catch (IOException e){
// e.printStackTrace();
/**
* 第三个参数,重回队列;如果设置为true,则消息重回到queue,broker会重新发消息给消费端
*/
channel.basicNack(deliveryTag,true,true);
}
}
}
整理博客不易,觉得有帮助的小伙伴点个赞吧~感谢收看!