Java implements rabbitmq routing model (routing/topic queues), producer consumer exchange message queue

In the fanout model, a break will be consumed by all subscribed queues, and consumers bound to the corresponding exchange can receive the message. But in some scenarios, we want different messages to be sent to different queues and consumed by different Xiafei. At this time, we need to use Direct type switches. For example, logs are divided into multiple types such as warn, info, and error. In the error log, you only need to see the error type log. In all logs, multiple types of logs need to be recorded.

As you can see in the official document, we give the sent message a binding key, that is, the secret key. When the queue receives the message, it needs to match the corresponding binding establishment, and the message that meets its own rules will be received.

Insert picture description here

  1. The producer
    first, we have to choose a direct type switch. At this time, my /vh virtual host provides a direct type switch named amq.direct by default. We may wish to redeclare a direct type switch of amqp.direct. It echoes the switch of the previous example.
public class Provider {
    
    
    public void send() throws IOException, TimeoutException {
    
    
        Connection connection = null;
        Channel channel = null;
        try {
    
    
            connection = ConnectionUtils.getConnection();
            // 获取连接通道
            channel = connection.createChannel();
            // 定义通道对应的交换机 参数一:交换机名称 参数二:类型 direct
            channel.exchangeDeclare("amqp.direct","direct");
            String routingKey = "info";
            // 发送消息
            channel.basicPublish("amqp.direct",routingKey,null,("direct message,routingKey为:" + routingKey + "," + System.currentTimeMillis()).getBytes());
        }finally {
    
    
            if (channel !=null && channel.isOpen()) {
    
    
                channel.close();
            }
            if (connection != null && connection.isOpen()) {
    
    
                connection.close();
            }
        }
    }

    public static void main(String[] args) throws IOException, TimeoutException {
    
    
        Provider provider = new Provider();
        provider.send();
    }
}

After executing the producer, because there is no switch in the code in the original switch list, rabbitmq will automatically create a corresponding switch.

  1. consumer

Consumer One:

public class Consumer01 {
    
    
    public void consume() throws IOException, TimeoutException {
    
    
        Connection connection = ConnectionUtils.getConnection();
        // 获取连接通道
        final Channel channel = connection.createChannel();
        // 绑定交换机
        channel.exchangeDeclare("amqp.direct","direct");
        //创建临时队列
        String queueName = channel.queueDeclare().getQueue();
        // 绑定交换机和队列
        channel.queueBind(queueName,"amqp.direct","info");
        channel.queueBind(queueName,"amqp.direct","warn");
        channel.queueBind(queueName,"amqp.direct","error");

        // 每次只能消费一个消息
        channel.basicQos(1);
        // 消费消息
        channel.basicConsume(queueName, false, new DefaultConsumer(channel) {
    
    
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
    
    
                System.out.println("消费消息:" + new String(body));
                //参数一:确认队列中的那个消息  参数二:是否开启多个消息同时确认
                channel.basicAck(envelope.getDeliveryTag(),false);
            }
        });
    }

    public static void main(String[] args) throws IOException, TimeoutException {
    
    
        Consumer01 consumer = new Consumer01();
        consumer.consume();
    }
}

Consumer 2:

public class Consumer02 {
    
    
    public void consume() throws IOException, TimeoutException {
    
    
        Connection connection = ConnectionUtils.getConnection();
        // 获取连接通道
        final Channel channel = connection.createChannel();
        // 绑定交换机
        channel.exchangeDeclare("amqp.direct","direct");
        //创建临时队列
        String queueName = channel.queueDeclare().getQueue();
        // 绑定交换机和队列
        channel.queueBind(queueName,"amqp.direct","error");

        // 每次只能消费一个消息
        channel.basicQos(1);
        // 消费消息
        channel.basicConsume(queueName, false, new DefaultConsumer(channel) {
    
    
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
    
    
                System.out.println("消费消息:" + new String(body));
                //参数一:确认队列中的那个消息  参数二:是否开启多个消息同时确认
                channel.basicAck(envelope.getDeliveryTag(),false);
            }
        });
    }
    public static void main(String[] args) throws IOException, TimeoutException {
    
    
        Consumer02 consumer = new Consumer02();
        consumer.consume();
    }

}

Three routingKeys of info, warn, and error are bound to consumer one, and a routingKey of error is bound to consumer two

  1. Test
    Start consumer one and consumer two, then start the producer, and send an info type message.

At this point:
Consumer 1 and
Insert picture description here
Consumer 2 are
Insert picture description herevisible, Consumer 1 has received the message, and Consumer 2 has not received it.
We send another error message.

At this point:
Consumer 1
Insert picture description hereConsumer 2
Insert picture description hereConsumers 1 and 2 both received the message with the routingKey of error, so that you can control which messages are sent to which queues according to the routingKey.

Guess you like

Origin blog.csdn.net/qq_41885819/article/details/112882630