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

In the routing routing model, we have realized that messages can be selectively sent to the corresponding message queue based on the routingKey, but this model is not flexible enough, for example, at the beginning there are only three types of logs: warn, info, error, But if you need to add fetal type logs later, you need to modify the original code, which does not conform to the opening and closing principles. Using the topic model can better meet this point, and supports wildcards for expansion.

Still, we can see detailed instructions in the official documents. The use *number can replace one word, and the use #number can replace zero or more words. So, when I want to adapt to all types of routingKey, just use the #number as the routingKey. In addition, rabbitmq officially recommends that we use it .to connect multiple words as routingKey.
Insert picture description here
The old rules, we need to use topic type switches this time, you can use the existing ones, or you can declare a new one yourself.

  1. Producer
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.topic","topic");
            String routingKey = "log.info";
            // 发送消息
            channel.basicPublish("amqp.topic",routingKey,null,("topic 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();
    }
}
  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.topic","topic");
        //创建临时队列
        String queueName = channel.queueDeclare().getQueue();
        // 绑定交换机和队列
        channel.queueBind(queueName,"amqp.topic","#");

        // 每次只能消费一个消息
        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();
    }
}

In consumer one, we use the #number as the routingKey to receive various types of messages.

Consumer 2:

public class Consumer02 {
    
    
    public void consume() throws IOException, TimeoutException {
    
    
        Connection connection = ConnectionUtils.getConnection();
        // 获取连接通道
        final Channel channel = connection.createChannel();
        // 绑定交换机
        channel.exchangeDeclare("amqp.topic","topic");
        //创建临时队列
        String queueName = channel.queueDeclare().getQueue();
        // 绑定交换机和队列
        channel.queueBind(queueName,"amqp.topic","*.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();
    }

}

Consumer II uses a *number instead of a word to receive .errora routingKey type message ending in it.

  1. Test
    Start consumer 1 and consumer 2, and then run the producer, send a message with routingKey log.info

Consumer 1:
Insert picture description hereConsumer 2:
Insert picture description hereImmediately, we send another message with a routingKey of file.error.
At this point, Consumer 1:
Insert picture description here
Consumer 2:
Insert picture description here

Guess you like

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