Five of the seven working modes of rabbitmq

The first: simple mode

Structure: 1 producer + 1 queue + 1 consumer
Diagram:
insert image description here
pom configuration file code:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.itheima</groupId>
    <artifactId>rabbitmq-producer</artifactId>
    <version>1.0-SNAPSHOT</version>


    <dependencies>
        <dependency>
            <groupId>com.rabbitmq</groupId>
            <artifactId>amqp-client</artifactId>
            <version>5.6.0</version>
        </dependency>
    </dependencies>


    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

Producer code:

package com.itheima.producer;

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 Producer_HelloWorld {
    
    
    public static void main(String[] args) throws IOException, TimeoutException {
    
    
        // 1.新建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();

        // 2.设置参数
        connectionFactory.setHost("192.168.64.129");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");

        // 3.获取连接 Connection
        Connection connection = connectionFactory.newConnection();

        // 4.创建channel
        Channel channel = connection.createChannel();

        // 5.创建队列Queue
        /**
         * String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments
         * queue: 队列名称
         * durable:是否持久化,重启之后还在
         * exclusive:是否独占,只能有一个消费这监听这个队列;当连接Connection关闭时,是否删除队列
         * autoDelete 是否自动删除
         * arguments 参数
         */
        // 如果不存在自动创建,如果存在使用原先的队列
        channel.queueDeclare("hello", true, false, false, null);

        // 6.发送消息
        /**
         * String exchange, String routingKey, BasicProperties props, byte[] body
         * exchange: 交换机名称,简单模式下使用默认的
         * routingKey:路由名称
         * props:配置信息
         * body:发送消息数据
         */
        String body = "Hello,World ~~~~~~~~~~~~~~~~~~~~";
        channel.basicPublish("", "hello",null, body.getBytes());

        // 7.释放资源
        channel.close();
        connection.close();
    }
}

Important information:
Note: The routingKey of the channel channel when publishing a message is the queue name matching regularity, that is to say, the routingKey determines which queue to send the message to.
When the resource is not closed, on the rabbitmq management interface, you can see the connection online, channel information, and the number of messages in the queue.
The connection is online: 5 messages in the
insert image description here
channel information queue have not been consumed
insert image description here

insert image description here

consumer code

package com.itheima.consumer;

import com.rabbitmq.client.*;

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

public class Consumer_Hello {
    
    
    public static void main(String[] args) throws IOException, TimeoutException {
    
    
        // 1.新建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();

        // 2.设置参数
        connectionFactory.setHost("192.168.64.129");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");

        // 3.获取连接 Connection
        Connection connection = connectionFactory.newConnection();

        // 4.创建channel
        Channel channel = connection.createChannel();

        // 5.接收消息
        /**
         * String queue, boolean autoAck, Consumer callback
         * queue: 队列名称
         * autoAck: 是否自动确认
         * callback: 回调对象
         */
        Consumer consumer = new DefaultConsumer(channel){
    
    
            // 当收到消息后,会自动执行该方法

            /**
             *
             * @param consumerTag 标识
             * @param envelope 获取对应信息,比如交换机、路由key。。
             * @param properties 配置
             * @param body 内容
             * @throws IOException 异常
             */
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
    
    
                System.out.println("consumerTag:"+ consumerTag);
                System.out.println("Exchange:"+ envelope.getExchange());
                System.out.println("RoutingKey:"+ envelope.getRoutingKey());
                System.out.println("properties:"+ properties);
                System.out.println("body:"+ new String(body));
            }
        };
        channel.basicConsume("hello", true, consumer);
        // 关闭资源?不要
    }
}

The second type: work queue

Structure: 1 producer + 1 queue + multiple consumers
Assign tasks among workers (competing consumer mode)
Analogy: Based on the simple mode, the number of consumers is increased
Diagram:
insert image description here
application scenario: too many tasks Improve the speed of processing tasks

The pom still has the configuration code for simple mode.

producer code

package com.itheima.producer;

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 Producer_WorkQueues {
    
    
    public static void main(String[] args) throws IOException, TimeoutException {
    
    
        // 1.新建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();

        // 2.设置参数
        connectionFactory.setHost("192.168.64.129");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");

        // 3.获取连接 Connection
        Connection connection = connectionFactory.newConnection();

        // 4.创建channel
        Channel channel = connection.createChannel();

        // 5.创建队列Queue
        /**
         * String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments
         * queue: 队列名称
         * durable:是否持久化,重启之后还在
         * exclusive:是否独占,只能有一个消费这监听这个队列;当连接Connection关闭时,是否删除队列
         * autoDelete 是否自动删除
         * arguments 参数
         */
        // 如果不存在自动创建,如果存在使用原先的队列
        channel.queueDeclare("work_queues", true, false, false, null);

        // 6.发送消息
        /**
         * String exchange, String routingKey, BasicProperties props, byte[] body
         * exchange: 交换机名称,简单模式下使用默认的
         * routingKey:路由名称
         * props:配置信息
         * body:发送消息数据
         */
        // 发10遍消息
        for (int i=1; i<=10; i++){
    
    
            String body = i+"Hello,workqueues ~~~~~~~~~~~~~~~~~~~~";
            channel.basicPublish("", "work_queues",null, body.getBytes());
        }


        // 7.释放资源
        channel.close();
        connection.close();
    }
}

consumer code

The first one:

package com.itheima.consumer;

import com.rabbitmq.client.*;

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

public class Consumer_WorkQueues1 {
    
    
    public static void main(String[] args) throws IOException, TimeoutException {
    
    
        // 1.新建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();

        // 2.设置参数
        connectionFactory.setHost("192.168.64.129");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");

        // 3.获取连接 Connection
        Connection connection = connectionFactory.newConnection();

        // 4.创建channel
        Channel channel = connection.createChannel();

        // 5.如果不存在自动创建,如果存在使用原先的队列
        channel.queueDeclare("work_queues", true, false, false, null);


        // 6.接收消息
        /**
         * String queue, boolean autoAck, Consumer callback
         * queue: 队列名称
         * autoAck: 是否自动确认
         * callback: 回调对象
         */
        Consumer consumer = new DefaultConsumer(channel){
    
    
            // 当收到消息后,会自动执行该方法

            /**
             *
             * @param consumerTag 标识
             * @param envelope 获取对应信息,比如交换机、路由key。。
             * @param properties 配置
             * @param body 内容
             * @throws IOException 异常
             */
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
    
    
                System.out.println("body:"+ new String(body));
            }
        };
        channel.basicConsume("work_queues", true, consumer);

        // 关闭资源?不要

    }
}

second:

package com.itheima.consumer;

import com.rabbitmq.client.*;

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

public class Consumer_WorkQueues2 {
    
    
    public static void main(String[] args) throws IOException, TimeoutException {
    
    
        // 1.新建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();

        // 2.设置参数
        connectionFactory.setHost("192.168.64.129");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");

        // 3.获取连接 Connection
        Connection connection = connectionFactory.newConnection();

        // 4.创建channel
        Channel channel = connection.createChannel();

        // 5.如果不存在自动创建,如果存在使用原先的队列
        channel.queueDeclare("work_queues", true, false, false, null);


        // 6.接收消息
        /**
         * String queue, boolean autoAck, Consumer callback
         * queue: 队列名称
         * autoAck: 是否自动确认
         * callback: 回调对象
         */
        Consumer consumer = new DefaultConsumer(channel){
    
    
            // 当收到消息后,会自动执行该方法

            /**
             *
             * @param consumerTag 标识
             * @param envelope 获取对应信息,比如交换机、路由key。。
             * @param properties 配置
             * @param body 内容
             * @throws IOException 异常
             */
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
    
    
                System.out.println("body:"+ new String(body));
            }
        };
        channel.basicConsume("work_queues", true, consumer);

        // 关闭资源?不要

    }
}

IMPORTANT: The consumer must be started first. When declaring the consumer, after creating the channel, declare the queue. The queue declared by the consumer must be the same as that of the producer.

The third type: publish and subscribe mode

Structure: 1 producer + 1 switch + multiple queues + multiple consumers
Analogy: Switches and queues are added to the work queue. Each consumer consumes the same message, there is no competition.
Graphic:
insert image description here
IMPORTANT INFORMATION:
Exchange: Switch (X). On the one hand, it receives the message sent by the producer, and on the other hand, it routes and processes the message. For example, delivery to a particular queue, delivery to all queues, or message discard.
There are three common types of switches:
Fanout: Broadcast, deliver messages to all queues bound to the switch
Direct: Direct, deliver messages to queues that match the specified routing key
Topic wildcard, deliver messages to queues that match the routing pattern (routing pattern)
The Exchange switch is only responsible for forwarding messages, and does not have the ability to store messages. Therefore, if there is no queue bound to Exchange, or if there is no queue that meets the routing rules, then the message will be lost!
insert image description here
insert image description here

producer code

package com.itheima.producer;

import com.rabbitmq.client.BuiltinExchangeType;
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 Producer_PubSub {
    
    
    public static void main(String[] args) throws IOException, TimeoutException {
    
    
        // 1.新建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();

        // 2.设置参数
        connectionFactory.setHost("192.168.64.129");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");

        // 3.获取连接 Connection
        Connection connection = connectionFactory.newConnection();

        // 4.创建channel
        Channel channel = connection.createChannel();

        // 5.创建交换机
        /**
         * String exchange, BuiltinExchangeType type, boolean durable, boolean autoDelete, boolean internal, Map<String, Object> arguments
         * exchange: 交换机名称
         * type: 枚举或字符串,交换机类型
         *     DIRECT("direct"), 定向
         *     FANOUT("fanout"), 广播(扇形),发送给每个队列
         *     TOPIC("topic"), 通配符
         *     HEADERS("headers"); 参数匹配
         * durable:是否持久化
         * autoDelete:是否自动删除
         * internal:内部使用。一般false
         * arguments:参数
         */
        String exchangeName = "test_fanout";
        channel.exchangeDeclare(exchangeName, BuiltinExchangeType.FANOUT,true,false,false,null);

        // 6.创建队列
        String queue1Name = "test_fanout_queue1";
        String queue2Name = "test_fanout_queue2";
        channel.queueDeclare(queue1Name,true,false,false,null);
        channel.queueDeclare(queue2Name,true,false,false,null);

        // 7.绑定队列和交换机
        /**
         * String queue, String exchange, String routingKey
         * queue: 队列名称
         * exchange: 交换机名称
         * routingKey: 路由键,绑定规则
         *  如果交换机类型为fanout,routingKey设置为""
         */
        channel.queueBind(queue1Name,exchangeName,"");
        channel.queueBind(queue2Name,exchangeName,"");

        // 8.发送消息
        /**
         * String exchange, String routingKey, BasicProperties props, byte[] body
         */
        String body = "日志消息:张三调用了findAll方法~~~~~~~~~~";
        channel.basicPublish(exchangeName,"",null,body.getBytes());

        // 9.释放资源
        channel.close();
        connection.close();

    }
}

consumer code

Consumer 1:

package com.itheima.consumer;

import com.rabbitmq.client.*;

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

public class Consumer_PubSub1 {
    
    
    public static void main(String[] args) throws IOException, TimeoutException {
    
    
        // 1.新建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();

        // 2.设置参数
        connectionFactory.setHost("192.168.64.129");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");

        // 3.获取连接 Connection
        Connection connection = connectionFactory.newConnection();

        // 4.创建channel
        Channel channel = connection.createChannel();

        // 5.如果不存在自动创建,如果存在使用原先的队列
        String queue1Name = "test_fanout_queue1";
        String queue2Name = "test_fanout_queue2";
        channel.queueDeclare(queue1Name, true, false, false, null);


        // 6.接收消息
        /**
         * String queue, boolean autoAck, Consumer callback
         * queue: 队列名称
         * autoAck: 是否自动确认
         * callback: 回调对象
         */
        Consumer consumer = new DefaultConsumer(channel){
    
    
            // 当收到消息后,会自动执行该方法

            /**
             *
             * @param consumerTag 标识
             * @param envelope 获取对应信息,比如交换机、路由key。。
             * @param properties 配置
             * @param body 内容
             * @throws IOException 异常
             */
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
    
    
                System.out.println("将日志信息打印到控制台~~~~~~~~~~~");
                System.out.println("body:"+ new String(body));
            }
        };
        channel.basicConsume(queue1Name, true, consumer);

        // 关闭资源?不要

    }
}

Consumer 2:

package com.itheima.consumer;

import com.rabbitmq.client.*;

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

public class Consumer_PubSub2 {
    
    
    public static void main(String[] args) throws IOException, TimeoutException {
    
    
        // 1.新建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();

        // 2.设置参数
        connectionFactory.setHost("192.168.64.129");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");

        // 3.获取连接 Connection
        Connection connection = connectionFactory.newConnection();

        // 4.创建channel
        Channel channel = connection.createChannel();

        // 5.如果不存在自动创建,如果存在使用原先的队列
        String queue1Name = "test_fanout_queue1";
        String queue2Name = "test_fanout_queue2";
        channel.queueDeclare(queue2Name, true, false, false, null);


        // 6.接收消息
        /**
         * String queue, boolean autoAck, Consumer callback
         * queue: 队列名称
         * autoAck: 是否自动确认
         * callback: 回调对象
         */
        Consumer consumer = new DefaultConsumer(channel){
    
    
            // 当收到消息后,会自动执行该方法

            /**
             *
             * @param consumerTag 标识
             * @param envelope 获取对应信息,比如交换机、路由key。。
             * @param properties 配置
             * @param body 内容
             * @throws IOException 异常
             */
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
    
    
                System.out.println("将日志信息保存到数据库~~~~~~~~");
                System.out.println("body:"+ new String(body));
            }
        };
        channel.basicConsume(queue2Name, true, consumer);

        // 关闭资源?不要

    }
}

Fourth: routing mode

Structure: 1 producer + 1 switch + multiple queues + multiple consumers
Analogy: In the publish-subscribe mode, the switch mode is broadcast, change it to direct, and add routingkey matching
Diagram:
insert image description here

Producer code:

package com.itheima.producer;

import com.rabbitmq.client.BuiltinExchangeType;
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 Producer_Routing {
    
    
    public static void main(String[] args) throws IOException, TimeoutException {
    
    
        // 1.新建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();

        // 2.设置参数
        connectionFactory.setHost("192.168.163.128");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");

        // 3.获取连接 Connection
        Connection connection = connectionFactory.newConnection();

        // 4.创建channel
        Channel channel = connection.createChannel();

        // 5.创建交换机
        /**
         * String exchange, BuiltinExchangeType type, boolean durable, boolean autoDelete, boolean internal, Map<String, Object> arguments
         * exchange: 交换机名称
         * type: 枚举或字符串,交换机类型
         *     DIRECT("direct"), 定向
         *     FANOUT("fanout"), 广播(扇形),发送给每个队列
         *     TOPIC("topic"), 通配符
         *     HEADERS("headers"); 参数匹配
         * durable:是否持久化
         * autoDelete:是否自动删除
         * internal:内部使用。一般false
         * arguments:参数
         */
        String exchangeName = "test_routing";
        channel.exchangeDeclare(exchangeName, BuiltinExchangeType.DIRECT,true,false,false,null);

        // 6.创建队列
        String queue1Name = "test_routing_queue1";
        String queue2Name = "test_routing_queue2";
        channel.queueDeclare(queue1Name,true,false,false,null);
        channel.queueDeclare(queue2Name,true,false,false,null);

        // 7.绑定队列和交换机
        /**
         * String queue, String exchange, String routingKey
         * queue: 队列名称
         * exchange: 交换机名称
         * routingKey: 路由键,绑定规则
         *  如果交换机类型为fanout,routingKey设置为""
         */
        // 第一个绑定通道和routingkey
        channel.queueBind(queue1Name,exchangeName,"error");
        // 第二个绑定通道和routingkey
        channel.queueBind(queue2Name,exchangeName,"warning");
        channel.queueBind(queue2Name,exchangeName,"info");
        channel.queueBind(queue2Name,exchangeName,"error");

        // 8.发送消息
        /**
         * String exchange, String routingKey, BasicProperties props, byte[] body
         */
        String body = "日志消息:info级别消息只有队列二打印~~~~~~~~~~";
        channel.basicPublish(exchangeName,"info",null,body.getBytes());

        // 9.释放资源
        channel.close();
        connection.close();

    }
}

Consumer 1 code:

package com.itheima.consumer;

import com.rabbitmq.client.*;

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

public class Consumer_Routing1 {
    
    
    public static void main(String[] args) throws IOException, TimeoutException {
    
    
        // 1.新建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();

        // 2.设置参数
        connectionFactory.setHost("192.168.163.128");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");

        // 3.获取连接 Connection
        Connection connection = connectionFactory.newConnection();

        // 4.创建channel
        Channel channel = connection.createChannel();

        // 5.如果不存在自动创建,如果存在使用原先的队列
        String queue1Name = "test_routing_queue1";
        String queue2Name = "test_routing_queue2";
        channel.queueDeclare(queue1Name, true, false, false, null);


        // 6.接收消息
        /**
         * String queue, boolean autoAck, Consumer callback
         * queue: 队列名称
         * autoAck: 是否自动确认
         * callback: 回调对象
         */
        Consumer consumer = new DefaultConsumer(channel){
    
    
            // 当收到消息后,会自动执行该方法

            /**
             *
             * @param consumerTag 标识
             * @param envelope 获取对应信息,比如交换机、路由key。。
             * @param properties 配置
             * @param body 内容
             * @throws IOException 异常
             */
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
    
    
                System.out.println("将日志信息打印到控制台~~~~~~~~~~~");
                System.out.println("body:"+ new String(body));
            }
        };
        channel.basicConsume(queue1Name, true, consumer);

        // 关闭资源?不要

    }
}

Consumer 2 code:

package com.itheima.consumer;

import com.rabbitmq.client.*;

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

public class Consumer_Routing2 {
    
    
    public static void main(String[] args) throws IOException, TimeoutException {
    
    
        // 1.新建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();

        // 2.设置参数
        connectionFactory.setHost("192.168.163.128");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");

        // 3.获取连接 Connection
        Connection connection = connectionFactory.newConnection();

        // 4.创建channel
        Channel channel = connection.createChannel();

        // 5.如果不存在自动创建,如果存在使用原先的队列
        String queue1Name = "test_routing_queue1";
        String queue2Name = "test_routing_queue2";
        channel.queueDeclare(queue2Name, true, false, false, null);


        // 6.接收消息
        /**
         * String queue, boolean autoAck, Consumer callback
         * queue: 队列名称
         * autoAck: 是否自动确认
         * callback: 回调对象
         */
        Consumer consumer = new DefaultConsumer(channel){
    
    
            // 当收到消息后,会自动执行该方法

            /**
             *
             * @param consumerTag 标识
             * @param envelope 获取对应信息,比如交换机、路由key。。
             * @param properties 配置
             * @param body 内容
             * @throws IOException 异常
             */
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
    
    
                System.out.println("将日志信息打印到控制台~~~~~~~~~~~");
                System.out.println("body:"+ new String(body));
            }
        };
        channel.basicConsume(queue2Name, true, consumer);

        // 关闭资源?不要

    }
}

The fifth wildcard pattern

Structure: 1 producer + 1 switch + multiple queues + multiple consumers
Analogy: In routing mode, the switch type is direct, and the switch in wildcard mode is topic. And routingKey can use asterisks and #. Asterisk describes 1 word, # means any word
Graphic:
insert image description here
producer code:

package com.itheima.producer;

import com.rabbitmq.client.BuiltinExchangeType;
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 Producer_Topic {
    
    
    public static void main(String[] args) throws IOException, TimeoutException {
    
    
        // 1.新建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();

        // 2.设置参数
        connectionFactory.setHost("192.168.163.128");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");

        // 3.获取连接 Connection
        Connection connection = connectionFactory.newConnection();

        // 4.创建channel
        Channel channel = connection.createChannel();

        // 5.创建交换机
        /**
         * String exchange, BuiltinExchangeType type, boolean durable, boolean autoDelete, boolean internal, Map<String, Object> arguments
         * exchange: 交换机名称
         * type: 枚举或字符串,交换机类型
         *     DIRECT("direct"), 定向
         *     FANOUT("fanout"), 广播(扇形),发送给每个队列
         *     TOPIC("topic"), 通配符
         *     HEADERS("headers"); 参数匹配
         * durable:是否持久化
         * autoDelete:是否自动删除
         * internal:内部使用。一般false
         * arguments:参数
         */
        String exchangeName = "test_topic";
        channel.exchangeDeclare(exchangeName, BuiltinExchangeType.TOPIC,true,false,false,null);

        // 6.创建队列
        String queue1Name = "test_topic_queue1";
        String queue2Name = "test_topic_queue2";
        channel.queueDeclare(queue1Name,true,false,false,null);
        channel.queueDeclare(queue2Name,true,false,false,null);

        // 7.绑定队列和交换机
        /**
         * String queue, String exchange, String routingKey
         * queue: 队列名称
         * exchange: 交换机名称
         * routingKey: 路由键,绑定规则
         *  如果交换机类型为fanout,routingKey设置为""
         */
        // 第一个绑定通道和routingkey
        channel.queueBind(queue1Name,exchangeName,"*.orange.*");
        // 第二个绑定通道和routingkey
        channel.queueBind(queue2Name,exchangeName,"*.*.rabbit");
        channel.queueBind(queue2Name,exchangeName,"Lazy.#");

        // 8.发送消息
        /**
         * String exchange, String routingKey, BasicProperties props, byte[] body
         */
        String body = "apple系统日志存入数据库";
        channel.basicPublish(exchangeName,"apple.good.rabbit",null,body.getBytes());
        String body2 = "orange系统日志打印控制台";
        channel.basicPublish(exchangeName,"gooad.orange.good",null,body2.getBytes());

        // 9.释放资源
        channel.close();
        connection.close();

    }
}

Consumer 1 code:

package com.itheima.consumer;

import com.rabbitmq.client.*;

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

public class Consumer_Topic1 {
    
    
    public static void main(String[] args) throws IOException, TimeoutException {
    
    
        // 1.新建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();

        // 2.设置参数
        connectionFactory.setHost("192.168.163.128");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");

        // 3.获取连接 Connection
        Connection connection = connectionFactory.newConnection();

        // 4.创建channel
        Channel channel = connection.createChannel();

        // 5.如果不存在自动创建,如果存在使用原先的队列
        String queue1Name = "test_topic_queue1";
        String queue2Name = "test_topic_queue2";
        channel.queueDeclare(queue1Name, true, false, false, null);


        // 6.接收消息
        /**
         * String queue, boolean autoAck, Consumer callback
         * queue: 队列名称
         * autoAck: 是否自动确认
         * callback: 回调对象
         */
        Consumer consumer = new DefaultConsumer(channel){
    
    
            // 当收到消息后,会自动执行该方法

            /**
             *
             * @param consumerTag 标识
             * @param envelope 获取对应信息,比如交换机、路由key。。
             * @param properties 配置
             * @param body 内容
             * @throws IOException 异常
             */
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
    
    
                System.out.println("将日志信息打印到控制台~~~~~~~~~~~");
                System.out.println("body:"+ new String(body));
            }
        };
        channel.basicConsume(queue1Name, true, consumer);

        // 关闭资源?不要

    }
}

Consumer 2 code:

package com.itheima.consumer;

import com.rabbitmq.client.*;

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

public class Consumer_Topic2 {
    
    
    public static void main(String[] args) throws IOException, TimeoutException {
    
    
        // 1.新建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();

        // 2.设置参数
        connectionFactory.setHost("192.168.163.128");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");

        // 3.获取连接 Connection
        Connection connection = connectionFactory.newConnection();

        // 4.创建channel
        Channel channel = connection.createChannel();

        // 5.如果不存在自动创建,如果存在使用原先的队列
        String queue1Name = "test_topic_queue1";
        String queue2Name = "test_topic_queue2";
        channel.queueDeclare(queue2Name, true, false, false, null);


        // 6.接收消息
        /**
         * String queue, boolean autoAck, Consumer callback
         * queue: 队列名称
         * autoAck: 是否自动确认
         * callback: 回调对象
         */
        Consumer consumer = new DefaultConsumer(channel){
    
    
            // 当收到消息后,会自动执行该方法

            /**
             *
             * @param consumerTag 标识
             * @param envelope 获取对应信息,比如交换机、路由key。。
             * @param properties 配置
             * @param body 内容
             * @throws IOException 异常
             */
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
    
    
                System.out.println("将日志信息存入数据库~~~~~~~~~~~");
                System.out.println("body:"+ new String(body));
            }
        };
        channel.basicConsume(queue2Name, true, consumer);

        // 关闭资源?不要

    }
}

Guess you like

Origin blog.csdn.net/m0_49382941/article/details/129239471