rabbit mq 随笔
简单生产者模型:
package com.atuigu.rabbitmq.simple;
import com.atuigu.rabbitmq.util.ConnectionUtil;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
/**
* 生产者
*/
public class Send {
private final static String QUEUE_NAME = "simple_queue";
public static void main(String[] argv) throws Exception {
// 获取到连接
Connection connection = ConnectionUtil.getConnection();
// 从连接中创建通道,使用通道才能完成消息相关的操作
Channel channel = connection.createChannel();
// 声明(创建)队列
//channel.queueDeclare(QUEUE_NAME, false, false, false, null);
//1,队列名称 2 是否持久化 3 是否排他(是否排除其他消费者) 4 是否自动删除(当出现异常情况是否删除队列) 5 是否有其他参数
channel.queueDeclare(QUEUE_NAME,false,false,false,null);
// 消息内容
String message = "Hello World!";
// 向指定的队列中发送消息 rabbitMQ 只能处理二进制的数据
channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
//打印消息
System.out.println(" [x] Sent '" + message + "'");
//关闭通道和连接
channel.close();
connection.close();
}
}
简单消费者模型:
package com.atuigu.rabbitmq.simple;
import com.atuigu.rabbitmq.util.ConnectionUtil;
import com.rabbitmq.client.*;
import java.io.IOException;
/**
* 消费者
*/
public class Recv {
private final static String QUEUE_NAME = "simple_queue";
public static void main(String[] argv) throws Exception {
// 获取到连接
Connection connection = ConnectionUtil.getConnection();
// 创建通道
Channel channel = connection.createChannel();
// 声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
// 定义队列的消费者
DefaultConsumer consumer = new DefaultConsumer(channel) {
// 获取消息,并且处理,这个方法类似事件监听,如果有消息的时候,会被自动调用
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,
byte[] body) throws IOException {
// body 即消息体
String msg = new String(body);
//int i =1/0;
System.out.println(" [x] received : " + msg + "!");
}
};
// 监听队列,第二个参数:是否自动进行消息确认。
//当消息出现异常,自动ick还是会接收消息,此时队列里的消息就已经没有了。当消息非常重要的时候,就需要用到手动ICK,以防止出现意外丢失消息。
channel.basicConsume(QUEUE_NAME, true, consumer);
}
}
1.怎么防止队列消息堆积
- 使用工作模型。多个消费者竞争消费队列信息。工作模型的消息只能被一个消费者消费一次。如果两个模块同时要获取消息,则不能使用work模型。
// 设置每个消费者同时只能处理一条消息 如果不设置的话,两个消费者获取的消息是一样的,不能使机器充分得到利用。 channel.basicQos(1);
2.交换机Exchange 只负责转发消息,不具备存储消息的能力。生产者绑定交换机,消费者使用队列绑定交换机。
必须先启动生产者,在启动消费者。不然消费者会因为没有交换机绑定而报错。因为交换机没有保存消息的能力,所以此时发送的消息直接会消失。
总结图:
怎么防止重复消费
MySQL 设置一个messegeID ,设置为唯一,当第一个消费者消费后,将messegeID存入数据库,然后当第二个消费者在消费的时候,存入数据库的时候检验messegeid ,当id相同就不允许存入数据库。