rabbitmq消费端的nack和重回队列的总结

消费者

package com.mq.rabbit.ack;

import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

/**
 * @Author Mqs
 * @Date 2018/10/28 22:14
 * @Desc
 */
public class Consumer {
    public static void main(String[] args)throws Exception {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setVirtualHost("/");
        factory.setPort(AMQP.PROTOCOL.PORT);
        factory.setHost("192.168.200.130");
        factory.setUsername("rollen");
        factory.setPassword("root");

        Connection connection = factory.newConnection();

        Channel channel = connection.createChannel();

        String routingKey = "ack_key";
        String exchangeName = "ack_exchange";
        String queueName = "ack_queue";
        String exchangeType = "topic";

        channel.exchangeDeclare(exchangeName, exchangeType, true, false, null);
        channel.queueDeclare(queueName, true, false, false, null);

        channel.queueBind(queueName, exchangeName, routingKey);

        // 由于消费段的ack是手工签收,所以 autoAck = false
        channel.basicConsume(queueName, false, new MyConsumer(channel));
    }
}

 

package com.mq.rabbit.ack;

import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import org.omg.CORBA.TRANSACTION_MODE;

import java.io.IOException;

/**
 * @Author Mqs
 * @Date 2018/10/28 22:45
 * @Desc
 */
public class MyConsumer extends DefaultConsumer {

    private Channel channel;
    /**
     * Constructs a new instance and records its association to the passed-in channel.
     *
     * @param channel the channel to which this consumer is attached
     */
    public MyConsumer(Channel channel) {
        super(channel);
        this.channel = channel;
    }

    @Override
    public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
        super.handleDelivery(consumerTag, envelope, properties, body);
        System.out.println("==properties: " + properties.getHeaders().get("pc"));
        Integer num = (Integer)properties.getHeaders().get("num");

        System.out.println("==body: " + new String(body));

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        /**
         * 第1条数据的num是0,会进到nack
         * 然后这条消息会从新回到队列
         * 回到队列的尾部,被重新消费
         */
        if (num == 0){
            // TODO 最后一个参数 requeue 设置为true 会把消费失败的消息从新添加到队列的尾端,设置为false不会重新回到队列
            channel.basicNack(envelope.getDeliveryTag(), false, true);
            System.out.println("==============第:" + num + "条消息------没有被消费");
        }else {
            System.out.println("==============第:" + num + "条消息-------被消费");
            channel.basicAck(envelope.getDeliveryTag(), false);
        }




    }
}

生产者

package com.mq.rabbit.ack;

import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author Mqs
 * @Date 2018/10/28 22:14
 * @Desc
 */
public class Producer {
    public static void main(String[] args)throws Exception {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setVirtualHost("/");
        factory.setPort(AMQP.PROTOCOL.PORT);
        factory.setHost("192.168.200.130");
        factory.setUsername("rollen");
        factory.setPassword("root");

        Connection connection = factory.newConnection();

        Channel channel = connection.createChannel();

        String routingKey = "ack_key";
        String exchangeName = "ack_exchange";

        String msg = "this is a message provide by ack producer";

        for (int i = 0; i < 5; i++){
            Map map = new HashMap<>();
            map.put("pc", "个人笔记本电脑");
            map.put("num", i);
            AMQP.BasicProperties properties = new AMQP.BasicProperties().builder()
                    .deliveryMode(2)
                    .contentEncoding("UTF-8")
                    .headers(map).build();

            channel.basicPublish(exchangeName, routingKey, true, properties, msg.getBytes());
            System.out.println("生产者发送第:" + i + " 条消息");
        }

    }
}

结果演示

==properties: 个人笔记本电脑
==body: this is a message provide by ack producer
==============第:0条消息------没有被消费
==properties: 个人笔记本电脑
==body: this is a message provide by ack producer
==============第:1条消息-------被消费
==properties: 个人笔记本电脑
==body: this is a message provide by ack producer
==============第:2条消息-------被消费
==properties: 个人笔记本电脑
==body: this is a message provide by ack producer
==============第:3条消息-------被消费
==properties: 个人笔记本电脑
==body: this is a message provide by ack producer
==============第:4条消息-------被消费
==properties: 个人笔记本电脑
==body: this is a message provide by ack producer
==============第:0条消息------没有被消费
==properties: 个人笔记本电脑
==body: this is a message provide by ack producer
==============第:0条消息------没有被消费
==properties: 个人笔记本电脑
==body: this is a message provide by ack producer
==============第:0条消息------没有被消费
==properties: 个人笔记本电脑
==body: this is a message provide by ack producer

图解

第0条消息从新回到对列,但是就是一直无法被消费

rabbitmq消费端的nack和重回队列的总结_第1张图片

你可能感兴趣的:(RabbitMQ)