RabbitMQ——消費端限流策略

自定義消息提供者

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

import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class apiProductor {
    public static void main(String[] args) throws IOException, TimeoutException {

        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setPort(5672);
        // IP 地址
        connectionFactory.setHost("122.51.242.###");
        connectionFactory.setVirtualHost("/");

        Connection connection = connectionFactory.newConnection();

        Channel channel = connection.createChannel();

        channel.confirmSelect();

        String exchangeName = "test_qos_exchange";
        String routingKey = "qos.save";

        String msg = "Hello RabbitMQ Qos Message";
        for (int i = 0 ;i < 5; i++){
            channel.basicPublish(exchangeName,routingKey,true,null, msg.getBytes());
        }

    }
}

自定義消息消費者

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

import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class apiConsumer {
    public static void main(String[] args) throws IOException, TimeoutException {

        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setPort(5672);
        connectionFactory.setHost("122.51.242.170");
        connectionFactory.setVirtualHost("/");
        Connection connection = connectionFactory.newConnection();
        Channel channel = connection.createChannel();

        String exchangeName = "test_qos_exchange";
        String routingKey = "qos.#";
        String queueName = "test_qos_queue";

        channel.exchangeDeclare(exchangeName,"topic",true,false, null);
        channel.queueDeclare(queueName,true,false,false,null);
        channel.queueBind(queueName, exchangeName, routingKey);

/*
    
		void basicQos(int prefetchSize, int prefetchCount, boolean global) throws IOException;
		
          basicQos參數:
          prefetchSize  每條消息的大小
          global 應用在channel還是 consumer 層面, false 指後者
          prefetchCount 每次從block中 積攢的消息中拿取prefetchCount 條,用完後再發送,日常工作中設置爲 1
*/

        channel.basicQos(0, 1, false);
    /*
        String basicConsume(String queue, boolean autoAck, Consumer callback) throws IOException;

	    限流方式, 第一件事就是 autoAck 設置爲false  取消自動簽收  選擇了手工簽收
    */
        channel.basicConsume(queueName, false, new MyConsumer(channel));
    }
}

自定義Consumer

	注意:Spring boot 2.0 以後,取消了默認的Consumer, 而是必須採用自定義的 Consumer(可以通過繼承  DefaultConsumer 來實現)
	
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;

import java.io.IOException;

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
    {
        System.out.println("-------------consumer message---------------------");
        System.out.println("consumerTag ======= >>> " + consumerTag);
        System.out.println("envelope ======= >>> " + envelope);
        System.out.println("properties ======= >>> " + properties);
        System.out.println("body ======= >>> " + new String(body, "UTF-8"));

        //  multiple  設置爲false 表示不支持批量接收
        // 	這個方法會給blocker 一個應答,表示我們已經處理完這條消息了,可以進行下一條消息的處理
        channel.basicAck(envelope.getDeliveryTag(), false);
    }
}

運行結果:
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
注意

如果把 自定義的 MyConsumer 中的

        channel.basicAck(envelope.getDeliveryTag(), false);

註解掉, 則消費端只會顯示循環發送中的第一條消息,其他的消息堆積在服務器的Message中。
在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章