RabbitMQ(四)玩一玩RabbitMQ的持久化
-
消息的可靠性是RabbitMQ的一大特色,那么RabbitMQ是如何避免消息丢失?
- 消费者的ACK确认机制,可以防止消费者丢失消息
- 万一在消费者消费之前,RabbitMQ服务器宕机了,那消息也会丢失
-
想要将消息持久化,那么 路由和队列都要持久化 才可以
生产者
public class Sender {
public static void main(String[] args) {
//获得连接
Connection connection = ConnectionUtil.getConnection();
try {
//在连接中创建通道
Channel channel = connection.createChannel();
//声明路由
/**
* String var1: 路由名
* String var2: 路由类型
* topic : 模糊匹配的定向分发
* boolean var3: 持久化
*/
channel.exchangeDeclare("test_exchange_topic","topic",true);
//定义发送信息
String msg = "Hello everyone !";
/**
* 发送消息有四个参数
* String var1: (路由)交换机名称,当前是简单模式,也就是P2P模式,无交换机,所以名称为""
* String var2: 目标队列名称
* BasicProperties var3: 设置消息的属性(没有属性则为null)
* MessageProperties.PERSISTENT_TEXT_PLAIN : 消息持久化
* byte[] var4: 消息内容(只接受字节数组)
*/
channel.basicPublish("test_exchange_topic", "user.register", MessageProperties.PERSISTENT_TEXT_PLAIN, msg.getBytes());
System.out.println("生产者: " + msg);
channel.close();
} catch (Exception e) {
e.printStackTrace();
}
//释放资源
ConnectionUtil.close(connection);
}
}
消费者
public class Recer1 {
public static void main(String[] args) {
//获得连接
Connection connection = ConnectionUtil.getConnection();
try {
//获得通道(信道)
Channel channel = connection.createChannel();
//声明消息队列
//queueDeclare : 此方法有双重作用,如果队列不存在则创建队列,若队列存在则获取
/**
* 创建消息队列有五个参数
* String var1: 队列的名称
* boolean var2: 队列中的数据是否持久化
* boolean var3: 是否排外(是否支持扩展,当前队列只能自己用,不能给别人用)
* boolean var4: 是否自动删除(当队列的连接数为 0 时,队列会销毁,不管队列中是否还保存数据)
* Map<String, Object> var5: 队列参数(没有参数为null)
*/
channel.queueDeclare("test_exchange_topic_queue_1", true, false, false, null);
//绑定路由(关注)
/**
* String var1: 队列名
* String var2: 路由名
* String var3:
* 匹配用户开头的所有操作
*/
channel.queueBind("test_exchange_topic_queue_1","test_exchange_topic","user.#");
//从信道中获得消息
DefaultConsumer consumer = new DefaultConsumer(channel){
/**
* 交付处理,重写方法
* @param consumerTag 收件人信息
* @param envelope 信封,包裹上的快递标签
* @param properties 协议配置
* @param body 消息
* @throws IOException
*/
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
//将消息字节构建成字符串
//boby就是在队列中获取的消息
String string = new String(body);
System.out.println("消费者 1 : " + string);
}
};
//监听队列
/**
* String var1: 队列名称
* boolean var2: 自动消息确认
* Consumer var3: 从管道中获取信息
*/
channel.basicConsume("test_exchange_topic_queue_1",true,consumer);
} catch (IOException e) {
e.printStackTrace();
}
}
}