rabbitMQ

RabbitMQ

1.原始代码-生产消息

创建连接工厂、创建连接、创建频道
rabbitMQ_第1张图片
rabbitMQ_第2张图片

流程图和上面没啥确切关系,用来理解connection、频道、队列、交换机
rabbitMQ_第3张图片

2.原始代码-消费消息

connectionUtils
rabbitMQ_第4张图片
获取连接、创建频道、创建队列
rabbitMQ_第5张图片
监听消息
rabbitMQ_第6张图片rabbitMQ_第7张图片

3.创建消费者和生产者完整代码

生产者

package com.itheima.rabbitmq.simple;import com.rabbitmq.client.Channel;

import com.rabbitmq.client.Connection;

import com.rabbitmq.client.ConnectionFactory;public class Producer {static final String QUEUE_NAME = "simple_queue";public static void main(String[] args) throws Exception {

        //创建连接工厂

        ConnectionFactory connectionFactory = new ConnectionFactory();

        //主机地址;默认为 localhost

        connectionFactory.setHost("localhost");

        //连接端口;默认为 5672

        connectionFactory.setPort(5672);

        //虚拟主机名称;默认为 /

        connectionFactory.setVirtualHost("/itcast");

        //连接用户名;默认为guest

        connectionFactory.setUsername("heima");

        //连接密码;默认为guest

        connectionFactory.setPassword("heima");//创建连接

        Connection connection = connectionFactory.newConnection();// 创建频道

        Channel channel = connection.createChannel();// 声明(创建)队列

        /**

         * 参数1:队列名称

         * 参数2:是否定义持久化队列

         * 参数3:是否独占本次连接

         * 参数4:是否在不使用的时候自动删除队列

         * 参数5:队列其它参数

         */

        channel.queueDeclare(QUEUE_NAME, true, false, false, null);// 要发送的信息

        String message = "你好;小兔子!";

        /**

         * 参数1:交换机名称,如果没有指定则使用默认Default Exchage

         * 参数2:路由key,简单模式可以传递队列名称

         * 参数3:消息其它属性

         * 参数4:消息内容

         */

        channel.basicPublish("", QUEUE_NAME, null, message.getBytes());

        System.out.println("已发送消息:" + message);// 关闭资源

        channel.close();

        connection.close();

    }

}

消费者

package com.itheima.rabbitmq.simple;import com.itheima.rabbitmq.util.ConnectionUtil;

import com.rabbitmq.client.*;import java.io.IOException;public class Consumer {public static void main(String[] args) throws Exception {

        Connection connection = ConnectionUtil.getConnection();// 创建频道

        Channel channel = connection.createChannel();// 声明(创建)队列

        /**

         * 参数1:队列名称

         * 参数2:是否定义持久化队列

         * 参数3:是否独占本次连接

         * 参数4:是否在不使用的时候自动删除队列

         * 参数5:队列其它参数

         */

        channel.queueDeclare(Producer.QUEUE_NAME, true, false, false, null);//创建消费者;并设置消息处理

        DefaultConsumer consumer = new DefaultConsumer(channel){

            @Override

            /**

             * consumerTag 消息者标签,在channel.basicConsume时候可以指定

             * envelope 消息包的内容,可从中获取消息id,消息routingkey,交换机,消息和重传标志(收到消息失败后是否需要重新发送)

             * properties 属性信息

             * body 消息

             */

            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {

                //路由key

                System.out.println("路由key为:" + envelope.getRoutingKey());

                //交换机

                System.out.println("交换机为:" + envelope.getExchange());

                //消息id

                System.out.println("消息id为:" + envelope.getDeliveryTag());

                //收到的消息

                System.out.println("接收到的消息为:" + new String(body, "utf-8"));

            }

        };

        //监听消息

        /**

         * 参数1:队列名称

         * 参数2:是否自动确认,设置为true为表示消息接收到自动向mq回复接收到了,mq接收到回复会删除消息,设置为false则需要手动确认

         * 参数3:消息接收到后回调

         */

        channel.basicConsume(Producer.QUEUE_NAME, true, consumer);//不关闭资源,应该一直监听消息

        //channel.close();

        //connection.close();

    }

}

以上这些都是基于这张图
rabbitMQ_第8张图片

4.AMQP

4.1相关概念

rabbitMQ_第9张图片

4.2RabbitMQ运转流程

在这里插入图片描述rabbitMQ_第10张图片

5.RabbitMQ工作模式

5.1Work queues工作队列模式

c1和c2会通过轮询的方式抢夺队列里面的消息
rabbitMQ_第11张图片

1)生产者

package com.itheima.rabbitmq.work;import com.itheima.rabbitmq.util.ConnectionUtil;

import com.rabbitmq.client.Channel;

import com.rabbitmq.client.Connection;

import com.rabbitmq.client.ConnectionFactory;public class Producer {static final String QUEUE_NAME = "work_queue";public static void main(String[] args) throws Exception {//创建连接

        Connection connection = ConnectionUtil.getConnection();// 创建频道

        Channel channel = connection.createChannel();// 声明(创建)队列

        /**

         * 参数1:队列名称

         * 参数2:是否定义持久化队列

         * 参数3:是否独占本次连接

         * 参数4:是否在不使用的时候自动删除队列

         * 参数5:队列其它参数

         */

        channel.queueDeclare(QUEUE_NAME, true, false, false, null);for (int i = 1; i <= 30; i++) {

            // 发送信息

            String message = "你好;小兔子!work模式--" + i;

            /**

             * 参数1:交换机名称,如果没有指定则使用默认Default Exchage

             * 参数2:路由key,简单模式可以传递队列名称

             * 参数3:消息其它属性

             * 参数4:消息内容

             */

            channel.basicPublish("", QUEUE_NAME, null, message.getBytes());

            System.out.println("已发送消息:" + message);

        }// 关闭资源

        channel.close();

        connection.close();

    }

}

4)消费者1

package com.itheima.rabbitmq.work;import com.itheima.rabbitmq.util.ConnectionUtil;

import com.rabbitmq.client.*;import java.io.IOException;public class Consumer1 {public static void main(String[] args) throws Exception {

        Connection connection = ConnectionUtil.getConnection();// 创建频道

        Channel channel = connection.createChannel();// 声明(创建)队列

        /**

         * 参数1:队列名称

         * 参数2:是否定义持久化队列

         * 参数3:是否独占本次连接

         * 参数4:是否在不使用的时候自动删除队列

         * 参数5:队列其它参数

         */

        channel.queueDeclare(Producer.QUEUE_NAME, true, false, false, null);//一次只能接收并处理一个消息

        channel.basicQos(1);//创建消费者;并设置消息处理

        DefaultConsumer consumer = new DefaultConsumer(channel){

            @Override

            /**

             * consumerTag 消息者标签,在channel.basicConsume时候可以指定

             * envelope 消息包的内容,可从中获取消息id,消息routingkey,交换机,消息和重传标志(收到消息失败后是否需要重新发送)

             * properties 属性信息

             * body 消息

             */

            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {

                try {

                    //路由key

                    System.out.println("路由key为:" + envelope.getRoutingKey());

                    //交换机

                    System.out.println("交换机为:" + envelope.getExchange());

                    //消息id

                    System.out.println("消息id为:" + envelope.getDeliveryTag());

                    //收到的消息

                    System.out.println("消费者1-接收到的消息为:" + new String(body, "utf-8"));

                    Thread.sleep(1000);//确认消息

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

                } catch (InterruptedException e) {

                    e.printStackTrace();

                }

            }

        };

        //监听消息

        /**

         * 参数1:队列名称

         * 参数2:是否自动确认,设置为true为表示消息接收到自动向mq回复接收到了,mq接收到回复会删除消息,设置为false则需要手动确认

         * 参数3:消息接收到后回调

         */

        channel.basicConsume(Producer.QUEUE_NAME, false, consumer);

    }

}

4)消费者2

package com.itheima.rabbitmq.work;import com.itheima.rabbitmq.util.ConnectionUtil;

import com.rabbitmq.client.*;import java.io.IOException;public class Consumer2 {public static void main(String[] args) throws Exception {

        Connection connection = ConnectionUtil.getConnection();// 创建频道

        Channel channel = connection.createChannel();// 声明(创建)队列

        /**

         * 参数1:队列名称

         * 参数2:是否定义持久化队列

         * 参数3:是否独占本次连接

         * 参数4:是否在不使用的时候自动删除队列

         * 参数5:队列其它参数

         */

        channel.queueDeclare(Producer.QUEUE_NAME, true, false, false, null);//一次只能接收并处理一个消息

        channel.basicQos(1);//创建消费者;并设置消息处理

        DefaultConsumer consumer = new DefaultConsumer(channel){

            @Override

            /**

             * consumerTag 消息者标签,在channel.basicConsume时候可以指定

             * envelope 消息包的内容,可从中获取消息id,消息routingkey,交换机,消息和重传标志(收到消息失败后是否需要重新发送)

             * properties 属性信息

             * body 消息

             */

            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {

                try {

                    //路由key

                    System.out.println("路由key为:" + envelope.getRoutingKey());

                    //交换机

                    System.out.println("交换机为:" + envelope.getExchange());

                    //消息id

                    System.out.println("消息id为:" + envelope.getDeliveryTag());

                    //收到的消息

                    System.out.println("消费者2-接收到的消息为:" + new String(body, "utf-8"));

                    Thread.sleep(1000);//确认消息

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

                } catch (InterruptedException e) {

                    e.printStackTrace();

                }

            }

        };

        //监听消息

        /**

         * 参数1:队列名称

         * 参数2:是否自动确认,设置为true为表示消息接收到自动向mq回复接收到了,mq接收到回复会删除消息,设置为false则需要手动确认

         * 参数3:消息接收到后回调

         */

        channel.basicConsume(Producer.QUEUE_NAME, false, consumer);

    }

}

5.2订阅模式类型

rabbitMQ_第12张图片

rabbitMQ_第13张图片

5.3Publish/Subscribe发布与订阅模式

rabbitMQ_第14张图片

1)生产者

package com.itheima.rabbitmq.ps;import com.itheima.rabbitmq.util.ConnectionUtil;

import com.rabbitmq.client.BuiltinExchangeType;

import com.rabbitmq.client.Channel;

import com.rabbitmq.client.Connection;/**

 * 发布与订阅使用的交换机类型为:fanout

 */

public class Producer {//交换机名称

    static final String FANOUT_EXCHAGE = "fanout_exchange";

    //队列名称

    static final String FANOUT_QUEUE_1 = "fanout_queue_1";

    //队列名称

    static final String FANOUT_QUEUE_2 = "fanout_queue_2";public static void main(String[] args) throws Exception {//创建连接

        Connection connection = ConnectionUtil.getConnection();// 创建频道

        Channel channel = connection.createChannel();/**

         * 声明交换机

         * 参数1:交换机名称

         * 参数2:交换机类型,fanout、topic、direct、headers

         */

        channel.exchangeDeclare(FANOUT_EXCHAGE, BuiltinExchangeType.FANOUT);// 声明(创建)队列

        /**

         * 参数1:队列名称

         * 参数2:是否定义持久化队列

         * 参数3:是否独占本次连接

         * 参数4:是否在不使用的时候自动删除队列

         * 参数5:队列其它参数

         */

        channel.queueDeclare(FANOUT_QUEUE_1, true, false, false, null);

        channel.queueDeclare(FANOUT_QUEUE_2, true, false, false, null);//队列绑定交换机

        channel.queueBind(FANOUT_QUEUE_1, FANOUT_EXCHAGE, "");

        channel.queueBind(FANOUT_QUEUE_2, FANOUT_EXCHAGE, "");for (int i = 1; i <= 10; i++) {

            // 发送信息

            String message = "你好;小兔子!发布订阅模式--" + i;

            /**

             * 参数1:交换机名称,如果没有指定则使用默认Default Exchage

             * 参数2:路由key,简单模式可以传递队列名称

             * 参数3:消息其它属性

             * 参数4:消息内容

             */

            channel.basicPublish(FANOUT_EXCHAGE, "", null, message.getBytes());

            System.out.println("已发送消息:" + message);

        }// 关闭资源

        channel.close();

        connection.close();

    }

}

2)消费者1

package com.itheima.rabbitmq.ps;import com.itheima.rabbitmq.util.ConnectionUtil;

import com.rabbitmq.client.*;import java.io.IOException;public class Consumer1 {public static void main(String[] args) throws Exception {

        Connection connection = ConnectionUtil.getConnection();// 创建频道

        Channel channel = connection.createChannel();//声明交换机

        channel.exchangeDeclare(Producer.FANOUT_EXCHAGE, BuiltinExchangeType.FANOUT);// 声明(创建)队列

        /**

         * 参数1:队列名称

         * 参数2:是否定义持久化队列

         * 参数3:是否独占本次连接

         * 参数4:是否在不使用的时候自动删除队列

         * 参数5:队列其它参数

         */

        channel.queueDeclare(Producer.FANOUT_QUEUE_1, true, false, false, null);//队列绑定交换机

        channel.queueBind(Producer.FANOUT_QUEUE_1, Producer.FANOUT_EXCHAGE, "");//创建消费者;并设置消息处理

        DefaultConsumer consumer = new DefaultConsumer(channel){

            @Override

            /**

             * consumerTag 消息者标签,在channel.basicConsume时候可以指定

             * envelope 消息包的内容,可从中获取消息id,消息routingkey,交换机,消息和重传标志(收到消息失败后是否需要重新发送)

             * properties 属性信息

             * body 消息

             */

            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {

                //路由key

                System.out.println("路由key为:" + envelope.getRoutingKey());

                //交换机

                System.out.println("交换机为:" + envelope.getExchange());

                //消息id

                System.out.println("消息id为:" + envelope.getDeliveryTag());

                //收到的消息

                System.out.println("消费者1-接收到的消息为:" + new String(body, "utf-8"));

            }

        };

        //监听消息

        /**

         * 参数1:队列名称

         * 参数2:是否自动确认,设置为true为表示消息接收到自动向mq回复接收到了,mq接收到回复会删除消息,设置为false则需要手动确认

         * 参数3:消息接收到后回调

         */

        channel.basicConsume(Producer.FANOUT_QUEUE_1, true, consumer);

    }

}

3)消费者2

package com.itheima.rabbitmq.ps;import com.itheima.rabbitmq.util.ConnectionUtil;

import com.rabbitmq.client.*;import java.io.IOException;public class Consumer2 {public static void main(String[] args) throws Exception {

        Connection connection = ConnectionUtil.getConnection();// 创建频道

        Channel channel = connection.createChannel();//声明交换机

        channel.exchangeDeclare(Producer.FANOUT_EXCHAGE, BuiltinExchangeType.FANOUT);// 声明(创建)队列

        /**

         * 参数1:队列名称

         * 参数2:是否定义持久化队列

         * 参数3:是否独占本次连接

         * 参数4:是否在不使用的时候自动删除队列

         * 参数5:队列其它参数

         */

        channel.queueDeclare(Producer.FANOUT_QUEUE_2, true, false, false, null);//队列绑定交换机

        channel.queueBind(Producer.FANOUT_QUEUE_2, Producer.FANOUT_EXCHAGE, "");//创建消费者;并设置消息处理

        DefaultConsumer consumer = new DefaultConsumer(channel){

            @Override

            /**

             * consumerTag 消息者标签,在channel.basicConsume时候可以指定

             * envelope 消息包的内容,可从中获取消息id,消息routingkey,交换机,消息和重传标志(收到消息失败后是否需要重新发送)

             * properties 属性信息

             * body 消息

             */

            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {

                //路由key

                System.out.println("路由key为:" + envelope.getRoutingKey());

                //交换机

                System.out.println("交换机为:" + envelope.getExchange());

                //消息id

                System.out.println("消息id为:" + envelope.getDeliveryTag());

                //收到的消息

                System.out.println("消费者2-接收到的消息为:" + new String(body, "utf-8"));

            }

        };

        //监听消息

        /**

         * 参数1:队列名称

         * 参数2:是否自动确认,设置为true为表示消息接收到自动向mq回复接收到了,mq接收到回复会删除消息,设置为false则需要手动确认

         * 参数3:消息接收到后回调

         */

        channel.basicConsume(Producer.FANOUT_QUEUE_2, true, consumer);

    }

}

rabbitMQ_第15张图片

5.4Routing路由模式

rabbitMQ_第16张图片

rabbitMQ_第17张图片

1)生产者

package com.itheima.rabbitmq.routing;import com.itheima.rabbitmq.util.ConnectionUtil;

import com.rabbitmq.client.BuiltinExchangeType;

import com.rabbitmq.client.Channel;

import com.rabbitmq.client.Connection;/**

 * 路由模式的交换机类型为:direct

 */

public class Producer {//交换机名称

    static final String DIRECT_EXCHAGE = "direct_exchange";

    //队列名称

    static final String DIRECT_QUEUE_INSERT = "direct_queue_insert";

    //队列名称

    static final String DIRECT_QUEUE_UPDATE = "direct_queue_update";public static void main(String[] args) throws Exception {//创建连接

        Connection connection = ConnectionUtil.getConnection();// 创建频道

        Channel channel = connection.createChannel();/**

         * 声明交换机

         * 参数1:交换机名称

         * 参数2:交换机类型,fanout、topic、direct、headers

         */

        channel.exchangeDeclare(DIRECT_EXCHAGE, BuiltinExchangeType.DIRECT);// 声明(创建)队列

        /**

         * 参数1:队列名称

         * 参数2:是否定义持久化队列

         * 参数3:是否独占本次连接

         * 参数4:是否在不使用的时候自动删除队列

         * 参数5:队列其它参数

         */

        channel.queueDeclare(DIRECT_QUEUE_INSERT, true, false, false, null);

        channel.queueDeclare(DIRECT_QUEUE_UPDATE, true, false, false, null);//队列绑定交换机

        channel.queueBind(DIRECT_QUEUE_INSERT, DIRECT_EXCHAGE, "insert");

        channel.queueBind(DIRECT_QUEUE_UPDATE, DIRECT_EXCHAGE, "update");// 发送信息

        String message = "新增了商品。路由模式;routing key 为 insert " ;

        /**

         * 参数1:交换机名称,如果没有指定则使用默认Default Exchage

         * 参数2:路由key,简单模式可以传递队列名称

         * 参数3:消息其它属性

         * 参数4:消息内容

         */

        channel.basicPublish(DIRECT_EXCHAGE, "insert", null, message.getBytes());

        System.out.println("已发送消息:" + message);// 发送信息

        message = "修改了商品。路由模式;routing key 为 update" ;

        /**

         * 参数1:交换机名称,如果没有指定则使用默认Default Exchage

         * 参数2:路由key,简单模式可以传递队列名称

         * 参数3:消息其它属性

         * 参数4:消息内容

         */

        channel.basicPublish(DIRECT_EXCHAGE, "update", null, message.getBytes());

        System.out.println("已发送消息:" + message);// 关闭资源

        channel.close();

        connection.close();

    }

}

2)消费者1

package com.itheima.rabbitmq.routing;import com.itheima.rabbitmq.util.ConnectionUtil;

import com.rabbitmq.client.*;import java.io.IOException;public class Consumer1 {public static void main(String[] args) throws Exception {

        Connection connection = ConnectionUtil.getConnection();// 创建频道

        Channel channel = connection.createChannel();//声明交换机

        channel.exchangeDeclare(Producer.DIRECT_EXCHAGE, BuiltinExchangeType.DIRECT);// 声明(创建)队列

        /**

         * 参数1:队列名称

         * 参数2:是否定义持久化队列

         * 参数3:是否独占本次连接

         * 参数4:是否在不使用的时候自动删除队列

         * 参数5:队列其它参数

         */

        channel.queueDeclare(Producer.DIRECT_QUEUE_INSERT, true, false, false, null);//队列绑定交换机

        channel.queueBind(Producer.DIRECT_QUEUE_INSERT, Producer.DIRECT_EXCHAGE, "insert");//创建消费者;并设置消息处理

        DefaultConsumer consumer = new DefaultConsumer(channel){

            @Override

            /**

             * consumerTag 消息者标签,在channel.basicConsume时候可以指定

             * envelope 消息包的内容,可从中获取消息id,消息routingkey,交换机,消息和重传标志(收到消息失败后是否需要重新发送)

             * properties 属性信息

             * body 消息

             */

            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {

                //路由key

                System.out.println("路由key为:" + envelope.getRoutingKey());

                //交换机

                System.out.println("交换机为:" + envelope.getExchange());

                //消息id

                System.out.println("消息id为:" + envelope.getDeliveryTag());

                //收到的消息

                System.out.println("消费者1-接收到的消息为:" + new String(body, "utf-8"));

            }

        };

        //监听消息

        /**

         * 参数1:队列名称

         * 参数2:是否自动确认,设置为true为表示消息接收到自动向mq回复接收到了,mq接收到回复会删除消息,设置为false则需要手动确认

         * 参数3:消息接收到后回调

         */

        channel.basicConsume(Producer.DIRECT_QUEUE_INSERT, true, consumer);

    }

}

3)消费者2

package com.itheima.rabbitmq.routing;import com.itheima.rabbitmq.util.ConnectionUtil;

import com.rabbitmq.client.*;import java.io.IOException;public class Consumer2 {public static void main(String[] args) throws Exception {

        Connection connection = ConnectionUtil.getConnection();// 创建频道

        Channel channel = connection.createChannel();//声明交换机

        channel.exchangeDeclare(Producer.DIRECT_EXCHAGE, BuiltinExchangeType.DIRECT);// 声明(创建)队列

        /**

         * 参数1:队列名称

         * 参数2:是否定义持久化队列

         * 参数3:是否独占本次连接

         * 参数4:是否在不使用的时候自动删除队列

         * 参数5:队列其它参数

         */

        channel.queueDeclare(Producer.DIRECT_QUEUE_UPDATE, true, false, false, null);//队列绑定交换机

        channel.queueBind(Producer.DIRECT_QUEUE_UPDATE, Producer.DIRECT_EXCHAGE, "update");//创建消费者;并设置消息处理

        DefaultConsumer consumer = new DefaultConsumer(channel){

            @Override

            /**

             * consumerTag 消息者标签,在channel.basicConsume时候可以指定

             * envelope 消息包的内容,可从中获取消息id,消息routingkey,交换机,消息和重传标志(收到消息失败后是否需要重新发送)

             * properties 属性信息

             * body 消息

             */

            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {

                //路由key

                System.out.println("路由key为:" + envelope.getRoutingKey());

                //交换机

                System.out.println("交换机为:" + envelope.getExchange());

                //消息id

                System.out.println("消息id为:" + envelope.getDeliveryTag());

                //收到的消息

                System.out.println("消费者2-接收到的消息为:" + new String(body, "utf-8"));

            }

        };

        //监听消息

        /**

         * 参数1:队列名称

         * 参数2:是否自动确认,设置为true为表示消息接收到自动向mq回复接收到了,mq接收到回复会删除消息,设置为false则需要手动确认

         * 参数3:消息接收到后回调

         */

        channel.basicConsume(Producer.DIRECT_QUEUE_UPDATE, true, consumer);

    }

}

5.5Topics通配符模式

rabbitMQ_第18张图片

1)生产者

package com.itheima.rabbitmq.topic;import com.itheima.rabbitmq.util.ConnectionUtil;

import com.rabbitmq.client.BuiltinExchangeType;

import com.rabbitmq.client.Channel;

import com.rabbitmq.client.Connection;/**

 * 通配符Topic的交换机类型为:topic

 */

public class Producer {//交换机名称

    static final String TOPIC_EXCHAGE = "topic_exchange";

    //队列名称

    static final String TOPIC_QUEUE_1 = "topic_queue_1";

    //队列名称

    static final String TOPIC_QUEUE_2 = "topic_queue_2";public static void main(String[] args) throws Exception {//创建连接

        Connection connection = ConnectionUtil.getConnection();// 创建频道

        Channel channel = connection.createChannel();/**

         * 声明交换机

         * 参数1:交换机名称

         * 参数2:交换机类型,fanout、topic、topic、headers

         */

        channel.exchangeDeclare(TOPIC_EXCHAGE, BuiltinExchangeType.TOPIC);

​

​

        // 发送信息

        String message = "新增了商品。Topic模式;routing key 为 item.insert " ;

        channel.basicPublish(TOPIC_EXCHAGE, "item.insert", null, message.getBytes());

        System.out.println("已发送消息:" + message);// 发送信息

        message = "修改了商品。Topic模式;routing key 为 item.update" ;

        channel.basicPublish(TOPIC_EXCHAGE, "item.update", null, message.getBytes());

        System.out.println("已发送消息:" + message);// 发送信息

        message = "删除了商品。Topic模式;routing key 为 item.delete" ;

        channel.basicPublish(TOPIC_EXCHAGE, "item.delete", null, message.getBytes());

        System.out.println("已发送消息:" + message);// 关闭资源

        channel.close();

        connection.close();

    }

}

2)消费者1

package com.itheima.rabbitmq.topic;import com.itheima.rabbitmq.util.ConnectionUtil;

import com.rabbitmq.client.*;import java.io.IOException;public class Consumer1 {public static void main(String[] args) throws Exception {

        Connection connection = ConnectionUtil.getConnection();// 创建频道

        Channel channel = connection.createChannel();//声明交换机

        channel.exchangeDeclare(Producer.TOPIC_EXCHAGE, BuiltinExchangeType.TOPIC);// 声明(创建)队列

        /**

         * 参数1:队列名称

         * 参数2:是否定义持久化队列

         * 参数3:是否独占本次连接

         * 参数4:是否在不使用的时候自动删除队列

         * 参数5:队列其它参数

         */

        channel.queueDeclare(Producer.TOPIC_QUEUE_1, true, false, false, null);//队列绑定交换机

        channel.queueBind(Producer.TOPIC_QUEUE_1, Producer.TOPIC_EXCHAGE, "item.update");

        channel.queueBind(Producer.TOPIC_QUEUE_1, Producer.TOPIC_EXCHAGE, "item.delete");//创建消费者;并设置消息处理

        DefaultConsumer consumer = new DefaultConsumer(channel){

            @Override

            /**

             * consumerTag 消息者标签,在channel.basicConsume时候可以指定

             * envelope 消息包的内容,可从中获取消息id,消息routingkey,交换机,消息和重传标志(收到消息失败后是否需要重新发送)

             * properties 属性信息

             * body 消息

             */

            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {

                //路由key

                System.out.println("路由key为:" + envelope.getRoutingKey());

                //交换机

                System.out.println("交换机为:" + envelope.getExchange());

                //消息id

                System.out.println("消息id为:" + envelope.getDeliveryTag());

                //收到的消息

                System.out.println("消费者1-接收到的消息为:" + new String(body, "utf-8"));

            }

        };

        //监听消息

        /**

         * 参数1:队列名称

         * 参数2:是否自动确认,设置为true为表示消息接收到自动向mq回复接收到了,mq接收到回复会删除消息,设置为false则需要手动确认

         * 参数3:消息接收到后回调

         */

        channel.basicConsume(Producer.TOPIC_QUEUE_1, true, consumer);

    }

}

2)消费者2

package com.itheima.rabbitmq.topic;import com.itheima.rabbitmq.util.ConnectionUtil;

import com.rabbitmq.client.*;import java.io.IOException;public class Consumer2 {public static void main(String[] args) throws Exception {

        Connection connection = ConnectionUtil.getConnection();// 创建频道

        Channel channel = connection.createChannel();//声明交换机

        channel.exchangeDeclare(Producer.TOPIC_EXCHAGE, BuiltinExchangeType.TOPIC);// 声明(创建)队列

        /**

         * 参数1:队列名称

         * 参数2:是否定义持久化队列

         * 参数3:是否独占本次连接

         * 参数4:是否在不使用的时候自动删除队列

         * 参数5:队列其它参数

         */

        channel.queueDeclare(Producer.TOPIC_QUEUE_2, true, false, false, null);//队列绑定交换机

        channel.queueBind(Producer.TOPIC_QUEUE_2, Producer.TOPIC_EXCHAGE, "item.*");//创建消费者;并设置消息处理

        DefaultConsumer consumer = new DefaultConsumer(channel){

            @Override

            /**

             * consumerTag 消息者标签,在channel.basicConsume时候可以指定

             * envelope 消息包的内容,可从中获取消息id,消息routingkey,交换机,消息和重传标志(收到消息失败后是否需要重新发送)

             * properties 属性信息

             * body 消息

             */

            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {

                //路由key

                System.out.println("路由key为:" + envelope.getRoutingKey());

                //交换机

                System.out.println("交换机为:" + envelope.getExchange());

                //消息id

                System.out.println("消息id为:" + envelope.getDeliveryTag());

                //收到的消息

                System.out.println("消费者2-接收到的消息为:" + new String(body, "utf-8"));

            }

        };

        //监听消息

        /**

         * 参数1:队列名称

         * 参数2:是否自动确认,设置为true为表示消息接收到自动向mq回复接收到了,mq接收到回复会删除消息,设置为false则需要手动确认

         * 参数3:消息接收到后回调

         */

        channel.basicConsume(Producer.TOPIC_QUEUE_2, true, consumer);

    }

}

6.SpringBoot整合RabbitMQ

rabbitMQ_第19张图片rabbitMQ_第20张图片

6.2搭建生产者工程

6.2.1创建工程

rabbitMQ_第21张图片

6.2.2添加依赖



<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.0modelVersion>

    <parent>

        <groupId>org.springframework.bootgroupId>

        <artifactId>spring-boot-starter-parentartifactId>

        <version>2.1.4.RELEASEversion>

    parent>

    <groupId>com.itheimagroupId>

    <artifactId>springboot-rabbitmq-producerartifactId>

    <version>1.0-SNAPSHOTversion><dependencies>

        <dependency>

            <groupId>org.springframework.bootgroupId>

            <artifactId>spring-boot-starter-webartifactId>

        dependency>

        <dependency>

            <groupId>org.springframework.bootgroupId>

            <artifactId>spring-boot-starter-amqpartifactId>

        dependency>

    dependencies>

project>

6.2.3启动类

package com.itheima.rabbitmq;import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication

public class ProducerApplication {

    public static void main(String[] args) {

        SpringApplication.run(ProducerApplication.class);

    }

}

6.2.4配置RabbitMQ

配置文件

spring:

  rabbitmq:

    host: localhost

    port: 5672

    virtual-host: /itcast

    username: heima

    password: heima

绑定交换机和队列
创建RabbitMQ队列与交换机绑定的配置类com.itheima.rabbitmq.config.RabbitMQConfig

package com.itheima.rabbitmq.config;import org.springframework.amqp.core.*;

import org.springframework.beans.factory.annotation.Qualifier;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;@Configuration

public class RabbitMQConfig {

    //交换机名称

    public static final String ITEM_TOPIC_EXCHANGE = "item_topic_exchange";

    //队列名称

    public static final String ITEM_QUEUE = "item_queue";//声明交换机

    @Bean("itemTopicExchange")

    public Exchange topicExchange(){

        return ExchangeBuilder.topicExchange(ITEM_TOPIC_EXCHANGE).durable(true).build();

    }//声明队列

    @Bean("itemQueue")

    public Queue itemQueue(){

        return QueueBuilder.durable(ITEM_QUEUE).build();

    }//绑定队列和交换机

    @Bean

    public Binding itemQueueExchange(@Qualifier("itemQueue") Queue queue,

                                     @Qualifier("itemTopicExchange") Exchange exchange){

        return BindingBuilder.bind(queue).to(exchange).with("item.#").noargs();

    }}

6.2.5消息发送Controller

我们创建一个SpringMVC的Controller方便我们进行测试

package com.itheima.rabbitmq.controller;import com.itheima.rabbitmq.config.RabbitMQConfig;

import org.springframework.amqp.rabbit.core.RabbitTemplate;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RequestParam;

import org.springframework.web.bind.annotation.RestController;/**

 * 发送消息的测试类

 */

@RestController

public class SendMsgController {//注入RabbitMQ的模板

    @Autowired

    private RabbitTemplate rabbitTemplate;/**

     * 测试

     */

    @GetMapping("/sendmsg")

    public String sendMsg(@RequestParam String msg, @RequestParam String key){/**

         * 发送消息

         * 参数一:交换机名称

         * 参数二:路由key

         * 参数三:发送的消息

         */

        rabbitTemplate.convertAndSend(RabbitMQConfig.ITEM_TOPIC_EXCHANGE ,key ,msg);//返回消息

        return "发送消息成功!";

    }

}

6.3搭建消费者工程

前三步同上

6.3.4配置RabbitMQ

配置文件

spring:

  rabbitmq:

    host: localhost

    port: 5672

    virtual-host: /itcast

    username: heima

    password: heima

6.3.5消息监听处理类

package com.itheima.rabbitmq.listener;import org.springframework.amqp.rabbit.annotation.RabbitListener;

import org.springframework.stereotype.Component;@Component

public class MyListener {/**

     * 监听某个队列的消息

     * @param message 接收到的消息

     */

    @RabbitListener(queues = "item_queue")

    public void myListener1(String message){

        System.out.println("消费者接收到的消息为:" + message);

    }

}

6.4效果图

rabbitMQ_第22张图片

你可能感兴趣的:(广告项目)