Confirm消息机制
消息的确认,是指生产者投递消息后,如果Broker收到消息,则会给我们生产者一个应答
生产者接收应答,用来确定这条消息是否正常发送到Broker,这种方式也是消息的可靠性传递的核心保障
确认
- channel开启确认模式 channel.confirmSelect()
- 在channel上加监听:addConfirmListerer,监听成功和失败的返回结果,根据具体结果对消息进行重新发送、或记录日志等后续处理
生产者端代码
public class Producer {
public static void main(String[] args) throws Exception {
//1 创建ConnectionFactory
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.17.17");
connectionFactory.setPort(5672);
connectionFactory.setVirtualHost("/");
//2 获取Connection
Connection connection = connectionFactory.newConnection();
//3 通过Connection创建一个新的Channel
Channel channel = connection.createChannel();
//4 指定我们的消息投递模式: 消息的确认模式
channel.confirmSelect();
String exchangeName = "test_confirm_exchange";
String routingKey = "confirm.save";
//5 发送一条消息
String msg = "Hello RabbitMQ Send confirm message!";
channel.basicPublish(exchangeName, routingKey, null, msg.getBytes());
//6 添加一个确认监听
channel.addConfirmListener(new ConfirmListener() {
@Override
public void handleNack(long deliveryTag, boolean multiple) throws IOException {
System.err.println("-------no ack!-----------");
}
//handleNack 失败时的处理
//磁盘写满 、MQ出现异常、Queue容量达到上限
@Override
public void handleAck(long deliveryTag, boolean multiple) throws IOException {
System.err.println("-------ack!-----------");
}
//handleAck 成功时的处理
//deliveryTag消息的唯一标签
//multiple 是否批量
});
}
}
Return消息机制
Return Listener用于处理一些不可路由的消息
我们的消息生产者,通过制定一个Exchange和RoutingKey,把消息送达到某一个队列中去,然后我们消费者监听队列,进行消费处理。但是在某些情况下,如果我们在发送消息的时候,当前的exchange不存在或指定的路由key路由不到,这个时候我们需要监听这种不可达的消息,Return Listener
API
Mandatory:如果true,则监听器会接收到路由不可达的消息,然后后续处理,如果为false,那么broker自动删除该消息
生产者端代码
public class Producer {
public static void main(String[] args) throws Exception {
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.17.17");
connectionFactory.setPort(5672);
connectionFactory.setVirtualHost("/");
Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel();
String exchange = "test_return_exchange";
String routingKey = "return.save";
String routingKeyError = "abc.save";
String msg = "Hello RabbitMQ Return Message";
//监控不可达消息
channel.addReturnListener(new ReturnListener() {
@Override
public void handleReturn(int replyCode, String replyText, String exchange,
String routingKey, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.err.println("---------handle return----------");
System.err.println("replyCode: " + replyCode);//响应码
System.err.println("replyText: " + replyText); //响应文本
System.err.println("exchange: " + exchange); //
System.err.println("routingKey: " + routingKey);
System.err.println("properties: " + properties);
System.err.println("body: " + new String(body));
}
});
channel.basicPublish(exchange, routingKeyError, true, null, msg.getBytes());
//第三个参数是Mandatory,Mandatory为true,才能使用return机制
//channel.basicPublish(exchange, routingKeyError, true, null, msg.getBytes());
}
}