这是我参与8月更文挑战的第30天,活动详情查看:8月更文挑战
代码
消费者
创建连接和信道
// 1.创建连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
// 2.设置属性 (设置连接的mq为本地的)
connectionFactory.setHost("localhost");
// 3.通过工厂创建连接
Connection connection = connectionFactory.newConnection();
// 4.通过连接创建channel(信道)
Channel channel = connection.createChannel();
创建交换机
- 交换机类型:"direct","fanout","topic","headers"
- durable:是否持久化消息,true表示持久化
- autoDelete:是否自动删除,当最后一个消费者不订阅,就自动删除
- internal:是否内置,内置交换机,客户端无法直接发送消息到该交换机,只能通过交换机路由到该交换机
// 可以自己创建交换机(交换机名称,交换机类型,(选填:durable,autoDelete,internal))
channel.exchangeDeclare("exchange","direct");
发布消息
当交换机名称为空白字符串时,使用默认的交direct交换机,路由键名称就是队列名
// 6.默认交换器(交换机名称(空白字符串代表默认交换机),路由名称(默认路由器的路由键就是队列名,这样就能绑定到该队列上),消息属性,消息)
channel.basicPublish("",QUEUE_NAME,null,message.getBytes());
// 指定交换器exchange
//channel.basicPublish("exchange",QUEUE_NAME,null,message.getBytes());
消费者
创建连接和信道
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("localhost");
Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel();
创建队列
// 创建队列(队列名称,durable是否持久化,exclusive是否排他,autoDelete是否自动删除,arguments队列的其他参数)
channel.queueDeclare(QUEUE_NAME,false,false,false,null);
消费者属性
接受到消息后,会确认消息,队列进行删除操作
两个参数
-
deliverTag:投递标签,用于确认是哪个消息确认
- 唯一标识每次投递,从1开始,每投递一次就会+1。
-
批量确认:开启批量确认,该消息及之前(标签小于这个消息)都会确认
- 可以减少网络流量
com.rabbitmq.client.Consumer consumer = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
//消息处理
System.out.println(body);
try {
// 消费者确认消息(deliverTag投递标签:表示是哪次消息,是否会消息的批量确认)
channel.basicAck(envelope.getDeliveryTag(), false);
} catch (Exception e) {
e.printStackTrace();
}
}
};
订阅
消费者订阅消息,之后的消息都会自动接收,可以选择是否自动确认。
// 订阅列队(队列名,接受消息是否自动确认)
channel.basicConsume(QUEUE_NAME,true,consumer);
关闭连接和信道。
消息拒绝
当超过消费者承载能力时,消费者可以选择拒绝消息。
basicNack(long deliveryTag, boolean multiple, boolean requeue)
- deliveryTag:消息的投递标签
- multiple:是否批量处理
- requeue:是否重新放回队列,否这条消息就会被丢弃。
channel.basicNack(envelope.getDeliveryTag(), false,true);