RabbitMQ消息可靠性投递、消息可靠性消费及消费端限流、消息过期时间TTL、死信及延迟队列
消息可靠性投递
-
确认模式(监听生产者发送消息到broker的消息丢失情况)
-
开启confirms
spring中配置文件设置ConnectionFactory的publisher-confirms="true" 开启确认模式。 springboot中设置spring.rabbitmq.publisher-confirms="true"
-
监听服务器回答
@Test public void testConfirm(){ //2. 定义回调 rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() { /** * @param correlationData 相关配置信息 * @param ack exchange交换机 是否成功收到了消息。true 成功,false代表失败 * @param cause 失败原因 */ @Override public void confirm(CorrelationData correlationData, boolean ack, String cause) { System.out.println("confirm方法被执行了...."); if (ack) { //接收成功 System.out.println("接收成功消息" + cause); } else { //接收失败 System.out.println("接收失败消息" + cause); //做一些处理,让消息再次发送。 } } }); rabbitTemplate.convertAndSend("boot_Ex","boot.haha","boot mq hello~~~"); }
-
-
退回模式(监听exchange到queue的消息丢失情况)
-
开启return
spring中配置文件设置ConnectionFactory的publisher-return="true" 开启退回模式。 springboot中配置文件设置spring.rabbitmq.publisher-return="true"
-
监听回调函数
/** * 回退模式: 当消息发送给Exchange后,Exchange路由到Queue失败是 才会执行 ReturnCallBack * 步骤: * 1. 开启回退模式:publisher-returns="true" * 2. 设置ReturnCallBack * 3. 设置Exchange处理消息的模式: * 1. 如果消息没有路由到Queue,则丢弃消息(默认) * 2. 如果消息没有路由到Queue,返回给消息发送方ReturnCallBack */ @Test public void testReturn() { //设置交换机处理失败消息的模式 rabbitTemplate.setMandatory(true); //2.设置ReturnCallBack rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() { /** * @param message 消息对象 * @param replyCode 错误码 * @param replyText 错误信息 * @param exchange 交换机 * @param routingKey 路由键 */ @Override public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) { System.out.println("return 执行了...."); System.out.println(message); System.out.println(replyCode); System.out.println(replyText); System.out.println(exchange); System.out.println(routingKey); //处理 } }); //3. 发送消息 rabbitTemplate.convertAndSend("boot_qu", "confirm", "message confirm...."); }
-
消息可靠性消费(Consumer Ack)
-
自动确认(默认):acknowledge=“none”
-
手动确认:acknowledge=“manual”
-
确认成功:channel.basicAck(消息的唯一ID,是否批量确认)
-
确认失败:channel.basicNack(消息的唯一ID,是否批量确认,是否重新把消息放回队列)
@Component public class AckListener implements ChannelAwareMessageListener { @Override public void onMessage(Message message, Channel channel) throws Exception { //消息唯一ID long deliveryTag = message.getMessageProperties().getDeliveryTag(); try { //1.接收转换消息 System.out.println(new String(message.getBody())); //2. 处理业务逻辑 System.out.println("处理业务逻辑..."); int i = 3/0;//出现错误 //3. 手动签收 channel.basicAck(deliveryTag,true); } catch (Exception e) { //e.printStackTrace(); //4.拒绝签收 /* 第三个参数:requeue:重回队列。如果设置为true,则消息重新回到queue,broker会重新发送该消息给消费端 */ channel.basicNack(deliveryTag,true,true); //channel.basicReject(deliveryTag,true); } } }
消费端限流
-
配置属性
listener-container属性perfetch = 1(表示消费端每次从mq拉去一条消息来消费,直到手动确认消费完毕后,才会继续拉去下一条消息。)
-
生产者发送多条消息(略)
-
接受消息
@Override public void onMessage(Message message, Channel channel) throws Exception { Thread.sleep(1000);