前面介绍消息中间件的概念,以及几种交换器的特性
也说了生产者生产消息,并发给交换器,由交换器将消息发给队列,再由绑定到队列上的消费者进行消费
本节学习生产者生产消息,发布时的几种方式
一、无保障
在之前的学习中,通过channel.basicPublish(EXCHANGE_NAME, routekey,null, message.getBytes());
发布并使用正确的交换器和路由信息,消息会被接收并发送到合适的队列中
但是如果出现: 1、网络问题,2、消息不可路由,3、RabbitMQ 自身有问题
这种方式就存在风险,无保证的消息发送一般情况下不推荐
二、失败确认
在发送消息时设置 mandatory 标志为true,channel.basicPublish(EXCHANGE_NAME,routekey,true,null,message.getBytes());
告诉RabbitMQ,如果消息不可路由,应该将消息返回给发送者,并通知失败
注意:它只会让RabbitMQ 向你通知失败,而不会通知成功
即如果消息正确路由到队列,则发布者不会收到任何通知
这叫导致无法确保发布消息一定是成功的,因为通知失败的消息可能会丢失
采用失败确认的方式,需设置一个回调,当生产者接收到RabbitMQ 的通知后,进行处理
//失败通知 回调
channel.addReturnListener(new ReturnListener() {
public void handleReturn(int replycode, String replyText, String exchange, String routeKey, AMQP.BasicProperties basicProperties, byte[] bytes) throws IOException {
String message = new String(bytes);
System.out.println("返回的replycode:"+replycode);
System.out.println("返回的replyText:"+replyText);
}
});
2.1 额外的监听器
当生产者监听到信道或者连接关闭时,可以进行相应处理
//TODO 回调
//连接关闭时执行
connection.addShutdownListener(new ShutdownListener() {
public void shutdownCompleted(ShutdownSignalException e) {
}
});
//TODO 回调
//信道关闭时执行
channel.addShutdownListener(new ShutdownListener() {
public void shutdownCompleted(ShutdownSignalException e) {
}
});
2.2 失败确认生产者完整demo
public class ProducerMandatory {
public final static String EXCHANGE_NAME = "mandatoryTest";
public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
//创建连接连接到RabbitMQ
ConnectionFactory factory = new ConnectionFactory();
// 设置MabbitMQ所在主机ip
factory.setHost("127.0.0.1");
// 创建一个连接
Connection connection = factory.newConnection();
// 创建一个信道
Channel channel = connection.createChannel();
// 指定Direct交换器
channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);
//TODO 回调
//连接关闭时执行
connection.addShutdownListener(new ShutdownListener() {
public void shutdownCompleted(ShutdownSignalException e) {
System.out.println("连接已关闭");
}
});
//TODO 回调
//信道关闭时执行
chan