rabbitmq的七种常用模式连接idea使用

本文详细介绍了RabbitMQ的五种常用消息传递模式,包括简单模式、工作者模式、发布订阅模式、路由模式和主题模式。每种模式通过实例展示了如何创建生产者和消费者,并解释了它们的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

rabbitmq的五种常用模式

官方网址
https://www.rabbitmq.com/getstarted.html

在这里插入图片描述

创建idea的maven项目

因为五种方式的结构一样,这边我就创建一个项目作为演示
(1)创建一个大的maven项目当作父项目
在这里插入图片描述(2)选择安装路径
在这里插入图片描述(3)在父项目下创建连个子项目
创建步骤和父项目一样
在这里插入图片描述
(4)效果展示
在这里插入图片描述(5)引入依赖
maven项目有一个特性,子类工程可以继承父类工程引得依赖
在这里插入图片描述

(1)简单模式

在这里插入图片描述

从图上可以看到只有三个角色:
  p 【product】: 生产者  发生消息的
  红色[queue]: 队列。  存储消息的
  C [consumer]: 消费者  消费消息

生产者(往队列中加入信息)


public class Product {
    public static void main(String[] args)throws  Exception {
        //创建连接工厂 --配置连接信息
        ConnectionFactory factory=new ConnectionFactory();
        //虚拟机的IP
        factory.setHost("192.168.213.188");
        //创建连接对象Connection
        Connection connection=factory.newConnection();
        //创建信道
        Channel channel = connection.createChannel();

        //创建队列
        /**
         * String queue, 队列的名称
         * boolean durable, 是否该队列持久化 rabbitMQ服务重启后该存放是否存在。
         * boolean exclusive, 是否独占 false
         * boolean autoDelete, 是否自动删除  如果长时间没有发生消息 则自动删除
         * Map<String, Object> arguments 额外参数  先给null
         */
        channel.queueDeclare("ban129_queue",true,false,false,null);
        //发生消息
        /**
         * String exchange: 交换机的名称 如果没有则使用“” 它回自动采用默认
         * String routingKey, 路由key  如果没有交换机的绑定 使用队列的名称
         * BasicProperties props, 消息的一些额外配置 目前先不加 null
         * byte[] body 消息的内容
         */
        String msg="holle!!!!!!!!!!!";
        channel.basicPublish("","ban129_queue",null,msg.getBytes());
    }
}

消费者(消费队列信息)



public class Consumer {
    public static void main(String[] args) throws Exception{
        //创建连接工厂 --配置连接信息
        ConnectionFactory factory=new ConnectionFactory();
        factory.setHost("192.168.213.188");
        //创建连接对象Connection
        Connection connection=factory.newConnection();
        //创建信道
        Channel channel = connection.createChannel();

        //接受消息
        /**
         * (String queue, 队列的名称
         *  boolean autoAck, 是否自动确认
         *  Consumer callback: 回调方法 当队列中存在信息后 会自动触发回调函数。
         */
        DefaultConsumer callback=new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                //body 接受的信息
                System.out.println("消息的内容:"+new String(body));
            }
        };
        channel.basicConsume("ban129_queue",true,callback);

    }
}

测试

  • [1 ] 先运行生产者
    在这里插入图片描述
  • [2 ]运行消费者
    -

(2)工作者模式

在这里插入图片描述

特点:   
 1. 一个生产者   
 2. 由多个消费。   
 3. 统一个队列。 
 4. 这些消费者之间存在竞争关系。
 用处:    比如批量处理上. rabbitMQ里面积压了大量的消息。 

生产者(往队列中加入信息)

public class Product {
    public static void main(String[] args)throws  Exception {
        //创建连接工厂 --配置连接信息
        ConnectionFactory factory=new ConnectionFactory();
        factory.setHost("192.168.213.188");
        //创建连接对象Connection
        Connection connection=factory.newConnection();
        //创建信道
        Channel channel = connection.createChannel();

        //创建队列
        /**
         * String queue, 队列的名称
         * boolean durable, 是否该队列持久化 rabbitMQ服务重启后该存放是否存在。
         * boolean exclusive, 是否独占 false
         * boolean autoDelete, 是否自动删除  如果长时间没有发生消息 则自动删除
         * Map<String, Object> arguments 额外参数  先给null
         */
        channel.queueDeclare("ban129_queue_work",true,false,false,null);
        //发生消息
        /**
         * String exchange: 交换机的名称 如果没有则使用“” 它回自动采用默认
         * String routingKey, 路由key  如果没有交换机的绑定 使用队列的名称
         * BasicProperties props, 消息的一些额外配置 目前先不加 null
         * byte[] body 消息的内容
         */
        for(int i=0;i<10;i++) {
            String msg = "冯昱凯真帅!!!!!!!!!!!"+i;
            channel.basicPublish("", "ban129_queue_work", null, msg.getBytes());
        }
        //生产者这里可以管理资源  消费者不能关闭资源。
        channel.close();
        connection.close();

    }
}

消费者01(消费队列信息)

public class Consumer01 {
    public static void main(String[] args) throws Exception{
        //创建连接工厂 --配置连接信息
        ConnectionFactory factory=new ConnectionFactory();
        factory.setHost("192.168.213.188");
        //创建连接对象Connection
        Connection connection=factory.newConnection();
        //创建信道
        Channel channel = connection.createChannel();

        //接受消息
        /**
         * (String queue, 队列的名称
         *  boolean autoAck, 是否自动确认
         *  Consumer callback: 回调方法 当队列中存在信息后 会自动触发回调函数。
         */
        DefaultConsumer callback=new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                //body 接受的信息
                try {
                    Thread.sleep(1000L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("消费者01:"+new String(body));
            }
        };
        channel.basicConsume("ban129_queue_work",true,callback);

    }
}

消费者02(消费队列信息)

public class Consumer02 {
    public static void main(String[] args) throws Exception{
        //创建连接工厂 --配置连接信息
        ConnectionFactory factory=new ConnectionFactory();
        factory.setHost("192.168.213.188");
        //创建连接对象Connection
        Connection connection=factory.newConnection();
        //创建信道
        Channel channel = connection.createChannel();

        //接受消息
        /**
         * (String queue, 队列的名称
         *  boolean autoAck, 是否自动确认
         *  Consumer callback: 回调方法 当队列中存在信息后 会自动触发回调函数。
         */
        DefaultConsumer callback=new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                //body 接受的信息
                try {
                    Thread.sleep(1000L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("消费者01:"+new String(body));
            }
        };
        channel.basicConsume("ban129_queue_work",true,callback);

    }
}

测试

  • [1 ] 先运行生产者
    在这里插入图片描述
  • [2 ]运行消费者01
    在这里插入图片描述
  • [3 ]运行消费者02
    在这里插入图片描述

总结

可以看到,在生产者往队列中加入100条信息后,消费者01(consumer1)和消费者02(consumer2)是采用交替处理的方式进行消费队列中的信息的

(3)发布订阅模式

在这里插入图片描述

特点:   
    1.一个生产者
    2.多个消费者
    3.多个队列。
    4.交换机 转发消息。

生产者(往队列中加入信息)

public class product1 {
    public static void main(String[] args) throws Exception{
        //创建工程
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("192.168.11.222");
        //获取对象
        Connection connection = connectionFactory.newConnection();
        //创建信道
        Channel channel = connection.createChannel();

        /**
         * (String queue, 队列的名称
         * boolean durable, 是否持久化
         * boolean exclusive,   是否独占
         * boolean autoDelete,  是否自动销毁
         * Map<String, Object> arguments 额外参数 不用就给空 null
         */
        channel.queueDeclare("ban129_fanout01",true,false,false,null);
        channel.queueDeclare("ban129_fanout02",true,false,false,null);

        //创建交换机
        /**
         * String exchange,交换机的名称
         * BuiltinExchangeType type, 交换机的类型
         * boolean durable:是否持久化
         */
        channel.exchangeDeclare("ban129_exchange", BuiltinExchangeType.FANOUT,true);
       //绑定交换机和队列
        /**
         * String queue,  队列名
         * String exchange, 交换机的名称
         * String routingKey:路由key 如果交换机为fanout模式则不需要路由key
         */
        channel.queueBind("ban129_fanout01","ban129_exchange","");
        channel.queueBind("ban129_fanout02","ban129_exchange","");
        //发生消息
        /**
         * String exchange: 交换机的名称 如果没有则使用“” 它回自动采用默认
         * String routingKey, 路由key  如果没有交换机的绑定 使用队列的名称
         * BasicProperties props, 消息的一些额外配置 目前先不加 null
         * byte[] body 消息的内容
         */
        for (int i = 0; i < 15; i++) {
            String msg = "刘亚飞真帅,好像没有见过他说话!!!!!!!!!!!"+i;
            channel.basicPublish("ban129_exchange","",null,msg.getBytes());
        }
    }
}

消费者01(消费队列信息)

public class Consumer1 {
    public static void main(String[] args) throws Exception{
        //创建 连接对象
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("192.168.11.222");
        Connection connection = factory.newConnection();

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

        //接受信息
        /**
         * (String queue, 队列的名称
         *  boolean autoAck, 是否自动确认
         *  Consumer callback: 回调方法 当队列中存在信息后 会自动触发回调函数。
         */
        DefaultConsumer consumer= new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("ababab1"+new String(body));
            }
        };
    channel.basicConsume("ban129_fanout01",true,consumer);

    }
}

消费者02(消费队列信息)

public class Consumer2 {
    public static void main(String[] args) throws Exception{
        //创建 连接对象
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("192.168.11.222");
        Connection connection = factory.newConnection();

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

        //接受信息
        /**
         * (String queue, 队列的名称
         *  boolean autoAck, 是否自动确认
         *  Consumer callback: 回调方法 当队列中存在信息后 会自动触发回调函数。
         */
        DefaultConsumer consumer= new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("ababab2"+new String(body));
            }
        };
    channel.basicConsume("ban129_fanout02",true,consumer);

    }
}

测试

  • [1 ] 先运行生产者
    在这里插入图片描述
  • [2 ]运行消费者01
    在这里插入图片描述
  • [3 ]运行消费者02
    在这里插入图片描述

总结

可以看到,在生产者往队列中加入15条信息后,队列1和队列2都接收到信息并存储信息,消费者01(consumer1)和消费者02(consumer2)对应不同的队列,都可以消费生产者发布的信息

(4)路由模式

在这里插入图片描述

特点:
    1.一个生产者
    2.多个消费者
    3.多个队列。
    4.交换机 转发消息。
    5.routekey:路由key 只要routekey匹配的消息可以到达对应队列。

生产者(往队列中加入信息)

public class Product1 {
    public static void main(String[] args) throws Exception{
        //创建连接
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("192.168.11.222");
        //获得对象
        Connection connection = factory.newConnection();
        //创建信道
        Channel channel = connection.createChannel();
        /**
         * String queue,队列的名称
         * boolean durable,是否持久化
         * boolean exclusive, 是否独占
         * boolean autoDelete, 是否自动删除
         * Map<String, Object> arguments 额外参数
         */
        channel.queueDeclare("ban129_queue_direct01",true,false,false,null);
        channel.queueDeclare("ban129_queue_direct02",true,false,false,null);

        //创建交换机
        /**
         * String exchange,交换机的名称
         * BuiltinExchangeType type, 交换机的类型
         * boolean durable:是否持久化
         */
        channel.exchangeDeclare("ban129_exchange_direct", BuiltinExchangeType.DIRECT,true);

        /**
         * String queue,  队列名
         * String exchange, 交换机的名称
         * String routingKey:路由key 如果交换机为fanout模式则不需要路由key
         */
        //绑定队列的路由key
        channel.queueBind("ban129_queue_direct01","ban129_exchange_direct","error");
        channel.queueBind("ban129_queue_direct02","ban129_exchange_direct","error");
        channel.queueBind("ban129_queue_direct02","ban129_exchange_direct","info");
        channel.queueBind("ban129_queue_direct02","ban129_exchange_direct","wange");

        /**
         * String exchange: 交换机的名称 如果没有则使用“” 它回自动采用默认
         * String routingKey, 路由key  如果没有交换机的绑定 使用队列的名称
         * BasicProperties props, 消息的一些额外配置 目前先不加 null
         * byte[] body 消息的内容
         */
        //发送消息
        for (int i = 0; i < 20; i++) {
            String msg= "加油"+i;
            channel.basicPublish("ban129_exchange_direct","error",null,msg.getBytes());
            channel.basicPublish("ban129_exchange_direct","info",null,msg.getBytes());
//            channel.basicPublish("ban129_exchange_direct","error",null,msg.getBytes());

        }
    }
}

消费者01(消费队列信息)

public class Consumer1 {
    public static void main(String[] args) throws Exception{
        //创建连接
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("192.168.11.222");
        //获得对象
        Connection connection = factory.newConnection();
        //创建信道
        Channel channel = connection.createChannel();

        //接收信息
        /**
         * (String queue, 队列的名称
         *  boolean autoAck, 是否自动确认
         *  Consumer callback: 回调方法 当队列中存在信息后 会自动触发回调函数。
         */
        DefaultConsumer consumer= new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("消费者1:"+new String(body));
            }
        };
        channel.basicConsume("ban129_queue_direct01",true,consumer);
    }
}

消费者02(消费队列信息)

public class Consumer2 {
    public static void main(String[] args) throws Exception{
        //创建连接
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("192.168.11.222");
        //获得对象
        Connection connection = factory.newConnection();
        //创建信道
        Channel channel = connection.createChannel();

        //接收信息
        /**
         * (String queue, 队列的名称
         *  boolean autoAck, 是否自动确认
         *  Consumer callback: 回调方法 当队列中存在信息后 会自动触发回调函数。
         */
        DefaultConsumer consumer= new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("消费者2:"+new String(body));
            }
        };
        channel.basicConsume("ban129_queue_direct02",true,consumer);
    }
}

测试

  • [1 ] 先运行生产者
    在这里插入图片描述

  • [2 ]运行消费者01
    在这里插入图片描述

  • [3 ]运行消费者02
    在这里插入图片描述

总结

可以看到,在生产者代码中给两个队列绑定了不同的路由key,在交换机往队列发信息时带了不同的路由key,只有队列绑定了此key才能成功往此队列发送信息。

(5)topic主体模式

整体代码于路由模式基本一样,只是交换机在绑定路由key时使用了通配符
在这里插入图片描述

1. 绑定按照通配符的模式。
     *: 统配一个单词。
     #: 统配n个单词

生产者

public class Product {
    public static void main(String[] args)throws  Exception {
        //创建连接工厂 --配置连接信息
        ConnectionFactory factory=new ConnectionFactory();
        factory.setHost("192.168.213.188");
        //创建连接对象Connection
        Connection connection=factory.newConnection();
        //创建信道
        Channel channel = connection.createChannel();

        //创建队列
        /**
         * String queue, 队列的名称
         * boolean durable, 是否该队列持久化 rabbitMQ服务重启后该存放是否存在。
         * boolean exclusive, 是否独占 false
         * boolean autoDelete, 是否自动删除  如果长时间没有发生消息 则自动删除
         * Map<String, Object> arguments 额外参数  先给null
         */
        channel.queueDeclare("ban129_queue_topic01",true,false,false,null);
        channel.queueDeclare("ban129_queue_topic02",true,false,false,null);

        //创建交换机
        /**
         * String exchange,交换机的名称
         * BuiltinExchangeType type, 交换机的类型
         * boolean durable:是否持久化
         */
        channel.exchangeDeclare("ban129_exchange_topic", BuiltinExchangeType.TOPIC,true);
        /**
         * String queue,  队列名
         * String exchange, 交换机的名称
         * String routingKey:路由key 如果交换机为fanout模式则不需要路由key
         */
        
//在绑定路由key时使用通配符 # 和 *         
channel.queueBind("ban129_queue_topic01","ban129_exchange_topic","*.orange.*");
              channel.queueBind("ban129_queue_topic02","ban129_exchange_topic","*.*.rabbit");
        channel.queueBind("ban129_queue_topic02","ban129_exchange_topic","lazy.#");

        //发生消息
        /**
         * String exchange: 交换机的名称 如果没有则使用“” 它回自动采用默认
         * String routingKey, 路由key  如果没有交换机的绑定 使用队列的名称
         * BasicProperties props, 消息的一些额外配置 目前先不加 null
         * byte[] body 消息的内容
         */
        for(int i=0;i<10;i++) {
            String msg = "你们有没有打疫苗!!!!!!!!!!!"+i;
            channel.basicPublish("ban129_exchange_topic", "lazy.orange.rabbit", null, msg.getBytes());
        }
        //生产者这里可以管理资源  消费者不能关闭资源。
        channel.close();
        connection.close();

    }
}

总结

在生产者代码中使用通配符给两个队列绑定了不同的路由key,在交换机往队列发信息时带了不同的路由key,只有队列绑定了此key才能成功往此队列发送信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值