123.RabbitMQ(一):mq下载和安装,mq的五大模型

目录

一、RabbitMQ的基本概念了解

1.什么是MQ

2.MQ有哪些

3.不同MQ特点

(1)ActiveMQ

(2)Kafka

(3)RocketMQ

(4)RabbitMQ

二、Rabbit的下载和安装

三、RabbitMQ之Helloworld模型(直连)

1.直连模型

2.直连模型的实例:生产者

(1)创建项目

(2)添加依赖

(3)rabbitmq中创建虚拟主机和用户

(4)设置一下目录结构

(5)创建一个生产者​

3.直连模型的实例:消费者

4.代码优化:连接工具类封装

5.API参数细节

(1)queueDeclared方法

四、RabbitMQ之Work Queues模型(工作队列)

1.工作队列任务模型

(1)使用场景

(2)模型解释

2.开发生产者

(1)先来重启一下rabbitmq

(2)开发生产者

(3)开发消费者

(4)能者多劳策略+消息永不丢失

五、RabbitMQ之Fanout模型(广播)

1.广播模型的流程

2.开发生产者

3.开发消费者

六、RabbitMQ之路由(Routing)

1.Direct模型(路由直连)

(1)模型图

(2)Direct模式的流程

(3)开发生产者

(4)开发消费者

2.Topic订阅模型(路由通配符)

(1)模型图

(2)开发生产者

(3)开发消费者

七、打赏请求


一、RabbitMQ的基本概念了解

1.什么是MQ

MQ(消息队列),通过典型的生产者和消费者模型,生产者不断地向消息队列中生产消息,消费者不断地从队列中获取消息。因为消息的生产和消费都是异步的,而且只关心消息的发送和接受,没有业务逻辑的进入,轻松的实现了系统的解耦。

MQ别名消息中间件,通过利用高效可靠的消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成

2.MQ有哪些

老牌的:ActiveMQ,RabbitMQ

炽手可热:Kafka

阿里研发的:RocketMQ

3.不同MQ特点

(1)ActiveMQ

优点:

        完全支持JMS规范,API丰富,多种集群架构模式

缺点:

       性能受约束,只适合中小型企业

(2)Kafka

优点:

        kafka主要特点是基于pull的模式来处理消息消费,追求高吞吐量,一开始的目的就是用于日志收集和传输。性能非常高。

缺点:

        不支持事务,对消息重复、丢失、错误没有严格要求,不适合做重要数据的mq

(3)RocketMQ

优点:

        性能不错,基于kafka开发,但是对可靠性做了优化

缺点:

        开源的RocketMQ不支持事务,需要花钱购买才支持

(4)RabbitMQ

优点:

        基于AMQP协议实现,AMQP天生就适合mq。还能与spring做无缝对接。对数据的一致性和可靠性是最高的。

缺点:

        源码使用Erlang语言开发的

二、Rabbit的下载和安装

官网地址:https://www.rabbitmq.com/#getstarted

我们使用docker来下载:

systemctl start docker

docker pull rabbitmq:3.8-management
 
docker run -d --hostname my-rabbit --name rabbit -p 15672:15672 -p 5672:5672 rabbitmq:3.8-management

注:如果你下载不下来,试试这个:

vi /etc/resolv.conf
 
 
#在里面添加如下
nameserver 8.8.8.8
nameserver 114.114.114.114

然后查看:

http://192.168.210.132:15672/#/ 

账号名和密码:guest

三、RabbitMQ之Helloworld模型(直连)

1.直连模型

这是第一种模型:直连模型

P:生产者

C:消费者

注:一个生产者只允许一个消费者使用(业务场景:登录发短信)

queue:消息队列,红色部分类似于一个邮箱,可以缓存消息。生产者向其中投递消息,消费者从其中取出消息

2.直连模型的实例:生产者

(1)创建项目

(2)添加依赖

    <!--引入rabbitmq的相关依赖-->
    <dependency>
      <groupId>com.rabbitmq</groupId>
      <artifactId>amqp-client</artifactId>
      <version>5.7.2</version>
    </dependency>

(3)rabbitmq中创建虚拟主机和用户

先来创建虚拟主机:

再来添加一个用户:

此处我们的用户就多了一个创建的ems:

将ems用户绑定到ems虚拟主机:

我们点击用户name:

至此我们ems用户和ems主机就

绑定上了:

(4)设置一下目录结构

懂的都懂:

(5)创建一个生产者

Provider:

package helloworld;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import org.junit.Test;

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

public class Provider {

    //生产消息
    @Test
    public void testSendMessage() throws IOException, TimeoutException {
        //创建连接mq的连接工厂对象
        ConnectionFactory connectionFactory = new ConnectionFactory();
        //设置连接rabbitmq主机
        connectionFactory.setHost("192.168.210.132");
        //设置端口号
        connectionFactory.setPort(5672);
        //设置连接哪个虚拟主机
        connectionFactory.setVirtualHost("/ems");
        //设置访问虚拟主机的用户名和密码
        connectionFactory.setUsername("ems");
        connectionFactory.setPassword("123");

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

        //获取连接中的通道
        Channel channel = connection.createChannel();

        //通道绑定对应消息队列
        //参数1:队列名称,如果队列不存在自动创建
        //参数2:用来定义队列特性是否要持久化,true持久化,false不持久化
        //参数3:是否独占队列,true独占,false不独占
        //参数4:是否在消费完成后自动删除队列,true自动删除,false不自动删除
        //参数5:额外附加参数
        channel.queueDeclare("hello",false,false,false,null);

        //发布消息
        //参数1:交换机名称
        //参数2:队列名称
        //参数3:传递消息额外参数
        //参数4:消息的具体内容
        channel.basicPublish("","hello",null,"hello rabbitnq".getBytes());

        channel.close();
        connection.close();
    }
}

编写完代码后我们运行两次,再看rabbitmq:

3.直连模型的实例:消费者

Consumer:

前面和生产者一样,就是这样离变成了消费者

package helloworld;

import com.rabbitmq.client.*;

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

public class Consumer {
    public static void main(String[] args) throws IOException, TimeoutException {


        //创建连接mq的连接工厂对象
        ConnectionFactory connectionFactory = new ConnectionFactory();
        //设置连接rabbitmq主机
        connectionFactory.setHost("192.168.210.132");
        //设置端口号
        connectionFactory.setPort(5672);
        //设置连接哪个虚拟主机
        connectionFactory.setVirtualHost("/ems");
        //设置访问虚拟主机的用户名和密码
        connectionFactory.setUsername("ems");
        connectionFactory.setPassword("123");

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

        //获取连接中的通道
        Channel channel = connection.createChannel();

        //通道绑定对应消息队列
        //参数1:队列名称,如果队列不存在自动创建
        //参数2:用来定义队列特性是否要持久化,true持久化,false不持久化
        //参数3:是否独占队列,true独占,false不独占
        //参数4:是否在消费完成后自动删除队列,true自动删除,false不自动删除
        //参数5:额外附加参数
        channel.queueDeclare("hello", false, false, false, null);

        //消费消息
        //参数1:消费哪个队列的消息,队列名称
        //参数2:开始消息的自动确认机制
        //参数3:消费时的回调接口
        channel.basicConsume("hello", true, new

                DefaultConsumer(channel) {

                    //最后一个参数:消息队列中取出的消息
                    @Override
                    public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws
                            IOException {
                        System.out.println("new String(body) = " + new String(body));
                    }
                });

        //消费端一直监听,不做关闭处理
    }
}

消费完之后再来看已经没了:

4.代码优化:连接工具类封装

新建一个工具类:RabbitMqUtils

RabbitMqUtils:

package helloworld.utils;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

public class RabbitMqUtils {

    private static ConnectionFactory connectionFactory;

    /**
     * 类加载执行,只执行一次
     */
    static {
        //创建连接mq的连接工厂对象
        connectionFactory = new ConnectionFactory();
        //设置连接rabbitmq主机
        connectionFactory.setHost("192.168.210.132");
        //设置端口号
        connectionFactory.setPort(5672);
        //设置连接哪个虚拟主机
        connectionFactory.setVirtualHost("/ems");
        //设置访问虚拟主机的用户名和密码
        connectionFactory.setUsername("ems");
        connectionFactory.setPassword("123");
    }

    /**
     * 定义提供连接对象的方法
     *
     * @return
     */
    public static Connection getConnection() {
        try {
            return connectionFactory.newConnection();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 关闭通道和关闭连接
     */
    public static void closeConnectionAndChannel(Channel channel, Connection connection) {
        try {
            if (channel != null) {
                channel.close();
            }
            if (connection != null) {
                connection.close();
            }
        } catch (Exception e) {

        }
    }

}

工具类的使用:

5.API参数细节

说在前面:生产者和消费者的特性设置要严格保持一致!

(1)queueDeclared方法

*1)第一个参数:队列名称,如果队列不存在自动创建

通道修改绑定的消息队列之后,还要再修改发布消息里的队列名,才可以在新队列中发布。

*2)第二个参数:用来定义队列特性是否要持久化,true持久化,false不持久化

如果是false,重启rabbitmq的话,这个队列就没了。如果不持久化,队列里还没消费的消息也就消失了。

注:就算设置了持久化,重启之后虽然队列还在,但是里面的消息还是没了,我们需要额外设置如下参数

MessageProperties.PERSISTENT_TEXT_PLAIN

*3)第三个参数:是否独占队列,true独占,false不独占。一般设置成false

*4)第四个参数:是否在消费完成后自动删除队列,true自动删除,false不自动删除

 当然消费者也要变成true,当消费完后关闭消费者,这个队列就会自动删除。

四、RabbitMQ之Work Queues模型(工作队列)

1.工作队列任务模型

Work Queues也叫任务模型。(工作中用的比较多)

(1)使用场景

当消息处理比较耗时时,可能生产消息的速度远远大于消息的消费速度,长此以往消息越堆积越多,无法及时处理。这个时候用任务模型。

多个消费者绑定到一个队列,共同消费队列中的消息。队列中的消息一旦消费就会消失,因此任务不会被重复执行。

(2)模型解释

P:生产者。任务的发布者

C1:消费者1,领取任务并且完成任务。假设完成速度比较慢

C2:消费者2,领取任务并且完成任务。假设完成速度比较快

2.开发生产者

(1)先来重启一下rabbitmq

然后登陆 http://192.168.210.132:15672/#/

通过点击队列名进去删除掉之前的队列:

(2)开发生产者

Provider:

package workqueue;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.MessageProperties;
import helloworld.utils.RabbitMqUtils;

import java.io.IOException;

public class Provider {
    public static void main(String[] args) throws IOException {
        //通过工具类获取连接对象
        Connection connection = RabbitMqUtils.getConnection();

        //获取连接中的通道
        Channel channel = connection.createChannel();

        //通过通道声明队列
        channel.queueDeclare("work",true,false,false,null);

        //生产消息
        for(int i = 0;i<10;i++) {
            channel.basicPublish("", "work", null, (i+"hello work queue").getBytes());
        }

        //关闭资源
        RabbitMqUtils.closeConnectionAndChannel(channel,connection);
    }
}

然后我们可以看到十个消息被生产了:

测试成功后就可以吧这个队列删除了

(3)开发消费者

Customer1和Customer2基本一致,除了sout的文字不同

package workqueue;

import com.rabbitmq.client.*;
import helloworld.utils.RabbitMqUtils;

import java.io.IOException;

public class Customer1 {
    public static void main(String[] args) throws IOException {
        //通过工具类获取连接对象
        Connection connection = RabbitMqUtils.getConnection();

        //获取连接中的通道
        Channel channel = connection.createChannel();

        //通道绑定对应消息队列
        channel.queueDeclare("work", true, false, false, null);

        //消费消息
        channel.basicConsume("work",true,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));
            }
        });

    }
}

开发好后,我们先启动消费者,再启动生产者,可以看到是轮询消费:

(4)能者多劳策略+消息永不丢失

上述模式有两个问题:

  1. 轮询消费,如果两个消费者速度不一样,慢的消费者会积压很多任务,快的消费者空转
  2. 10个任务一次性给到两个消费者,各5个任务。如果第一个消费者消费3个宕机了,后面2个任务就丢失了。

改造消费者Customer1和Customer2:

package workqueue;

import com.rabbitmq.client.*;
import helloworld.utils.RabbitMqUtils;

import java.io.IOException;

public class Customer1 {
    public static void main(String[] args) throws IOException {
        //通过工具类获取连接对象
        Connection connection = RabbitMqUtils.getConnection();

        //获取连接中的通道
        final Channel channel = connection.createChannel();

        //每次只能消费一个消息,避免一次性拿到5个,中途宕机导致后续消息丢失问题
        channel.basicQos(1);

        //通道绑定对应消息队列
        channel.queueDeclare("work", true, false, false, null);

        //消费消息
        //参数1:队列名称
        //参数2:消息自动确认,我们取消自动确认,进行手动确认
        channel.basicConsume("work",false,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("消费者-1:"+new String(body));

                //参数1:确认队列中哪个具体消息
                //参数2:是否开启多个消息同时确认
                channel.basicAck(envelope.getDeliveryTag(),false);
            }
        });

    }
}

测试结果:

五、RabbitMQ之Fanout模型(广播)

1.广播模型的流程

  • 可以有多个消费者
  • 每个消费者有自己的queue
  • 每个队列都要绑定到交换机
  • 生产者发送的消息,只能发送到交换机。交换机决定要发给哪个队列,生产者无法决定
  • 交换机把消息发送给绑定过的所有队列
  • 队列的消费者都能拿到消息,实现一条消息被多个消费者消费

2.开发生产者

Provider:

package fanout;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import helloworld.utils.RabbitMqUtils;

import java.io.IOException;

public class Provider {
    public static void main(String[] args) throws IOException {
        //通过工具类获取连接对象
        Connection connection = RabbitMqUtils.getConnection();

        //获取连接中的通道
        Channel channel = connection.createChannel();

        //将通道声明给指定交换机
        //参数1:交换机名称
        //参数2:交换机类型,fanout:广播类型
        channel.exchangeDeclare("logs","fanout");

        //发送消息
        //参数1:交换机名称
        //参数2:队列名称
        //参数3:传递消息额外参数
        //参数4:消息的具体内容
        channel.basicPublish("logs","",null,"fanout type message".getBytes());


        //关闭资源
        RabbitMqUtils.closeConnectionAndChannel(channel,connection);
    }
}

3.开发消费者

Customer1,Customer2,Customer3:

package fanout;

import com.rabbitmq.client.*;
import helloworld.utils.RabbitMqUtils;

import java.io.IOException;

public class Customer1 {
    public static void main(String[] args) throws IOException {
        //通过工具类获取连接对象
        Connection connection = RabbitMqUtils.getConnection();

        //获取连接中的通道
        final Channel channel = connection.createChannel();

        //通道绑定交换机
        channel.exchangeDeclare("logs","fanout");

        //临时队列
        String quueueName = channel.queueDeclare().getQueue();

        //绑定交换机和队列
        channel.queueBind(quueueName,"logs","");

        //消费消息
        channel.basicConsume(quueueName, true, 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));
                    }
                });



    }
}

测试发现,三个消费者都能收到广播的消息:

六、RabbitMQ之路由(Routing)

Fanout广播下,一条消息会被所有消费者消费。但是有时候我们希望不同消息被不同消息队列消费,这个时候可以用Direct模型(路由直连)。

1.Direct模型(路由直连)

(1)模型图

  • P:生产者,向Exchange发送消息,发送消息时会指定一个RoutingKey
  • X:Exchange(交换机),接受生产者的消息,然后把消息递交给RoutingKey完全匹配的队列
  • C1:消费者1,其所在队列指定了需要RoutingKey为error的消息
  • C2:消费者2,其所在队列指定了需要RoutingKey为info、error、warning的消息

(2)Direct模式的流程

  • 队列与交换机的绑定,不能是任意绑定了,而是要指定一个RoutingKey(路由key)
  • 消息的发送方在向Exchange发送消息时,也必须指定消息的RoutingKey
  • Exchange不再把消息交给每一个指定的队列,而是根据消息的RoutingKey进行判断,只有队列的RoutingKey与消息的RoutingKey完全一致,才会接受消息

(3)开发生产者

Provider:

package direct;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import helloworld.utils.RabbitMqUtils;

import java.io.IOException;

/**
 * [一句话描述该类的功能]
 *
 * @author : [xupeng]
 * @version : [v1.0]
 * @createTime : [2021/7/7 11:45]
 */
public class Provider {
	public static void main(String[] args) throws IOException {
		//通过工具类获取连接对象
		Connection connection = RabbitMqUtils.getConnection();

		//获取连接中的通道
		final Channel channel = connection.createChannel();

		String exchangeName = "logs_direct";

		//通过通道声明交换机
		//参数1:交换机名称
		//参数2:路由直连模式
		channel.exchangeDeclare(exchangeName, "direct");

		//发送消息
		String routingKey = "error";
		channel.basicPublish(exchangeName,routingKey,null,("direct模式发布的基于routingKey:"+routingKey+"发送的消息").getBytes());

		//关闭资源
		RabbitMqUtils.closeConnectionAndChannel(channel,connection);
	}
}

(4)开发消费者

Consumer1、Consumer2:
package direct;

import com.rabbitmq.client.*;
import helloworld.utils.RabbitMqUtils;

import java.io.IOException;

/**
 * [一句话描述该类的功能]
 *
 * @author : [xupeng]
 * @version : [v1.0]
 * @createTime : [2021/7/7 11:52]
 */
public class Consumer1 {
	public static void main(String[] args) throws IOException, IOException {
		//通过工具类获取连接对象
		Connection connection = RabbitMqUtils.getConnection();

		//获取连接中的通道
		final Channel channel = connection.createChannel();

		String exchangeName = "logs_direct";

		//通道声明交换机以及交换的类型
		channel.exchangeDeclare(exchangeName, "direct");

		//创建一个临时队列
		String queue = channel.queueDeclare().getQueue();

		//基于routingKey绑定队列和交换机
		//参数1:队列名
		//参数2:交换机名
		//参数3:routingKey
		channel.queueBind(queue, exchangeName, "error");

		//获取消费的消息
		channel.basicConsume(queue, true, 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));
			}
		});


	}
}
package direct;

import com.rabbitmq.client.*;
import helloworld.utils.RabbitMqUtils;

import java.io.IOException;

/**
 * [一句话描述该类的功能]
 *
 * @author : [xupeng]
 * @version : [v1.0]
 * @createTime : [2021/7/7 11:52]
 */
public class Consumer2 {
	public static void main(String[] args) throws IOException, IOException {
		//通过工具类获取连接对象
		Connection connection = RabbitMqUtils.getConnection();

		//获取连接中的通道
		final Channel channel = connection.createChannel();

		String exchangeName = "logs_direct";

		//通道声明交换机以及交换的类型
		channel.exchangeDeclare(exchangeName, "direct");

		//创建一个临时队列
		String queue = channel.queueDeclare().getQueue();

		//基于routingKey绑定队列和交换机
		//参数1:队列名
		//参数2:交换机名
		//参数3:routingKey
		channel.queueBind(queue, exchangeName, "error");
		channel.queueBind(queue, exchangeName, "info");
		channel.queueBind(queue, exchangeName, "warning");

		//获取消费的消息
		channel.basicConsume(queue, true, 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));
			}
		});


	}
}

测试:

2.Topic订阅模型(路由通配符)

Topic类型的Exchange与Direct相比,都是可以根据routingKey把消息路由到不同的队列,只不过Topic类型Exchange可以让队列在绑定routingKey的时候使用通配符

这种模型routingKey一般是由一个或多个单词组成,多个单词之间使用"."分隔。

(1)模型图

我们可看到通配符有"*"和"#"这两种:

  1. *:匹配不多不少,恰好一个词
  2. #:匹配一个或多个

(2)开发生产者

Provider:

package topic;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import helloworld.utils.RabbitMqUtils;

import java.io.IOException;

/**
 * [一句话描述该类的功能]
 *
 * @author : [xupeng]
 * @version : [v1.0]
 * @createTime : [2021/7/7 13:52]
 */
public class Provider {
	public static void main(String[] args) throws IOException {
		//通过工具类获取连接对象
		Connection connection = RabbitMqUtils.getConnection();

		//获取连接中的通道
		final Channel channel = connection.createChannel();

		String exchangeName = "topics";

		//通过通道声明交换机
		//参数1:交换机名称
		//参数2:路由直连模式
		channel.exchangeDeclare(exchangeName, "topic");

		//发送消息
		String routingKey = "user.save.list";
		channel.basicPublish(exchangeName,routingKey,null,("topic模式发布的基于routingKey:"+routingKey+"发送的消息").getBytes());

		//关闭资源
		RabbitMqUtils.closeConnectionAndChannel(channel,connection);
	}
}

(3)开发消费者

Consumer1,Consumer2:

package topic;

import com.rabbitmq.client.*;
import helloworld.utils.RabbitMqUtils;

import java.io.IOException;

/**
 * [一句话描述该类的功能]
 *
 * @author : [xupeng]
 * @version : [v1.0]
 * @createTime : [2021/7/7 11:52]
 */
public class Consumer1 {
	public static void main(String[] args) throws IOException, IOException {
		//通过工具类获取连接对象
		Connection connection = RabbitMqUtils.getConnection();

		//获取连接中的通道
		final Channel channel = connection.createChannel();

		String exchangeName = "topics";

		//通道声明交换机以及交换的类型
		channel.exchangeDeclare(exchangeName, "topic");

		//创建一个临时队列
		String queue = channel.queueDeclare().getQueue();

		//基于routingKey绑定队列和交换机
		//参数1:队列名
		//参数2:交换机名
		//参数3:routingKey
		channel.queueBind(queue, exchangeName, "user.*");

		//获取消费的消息
		channel.basicConsume(queue, true, 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));
			}
		});


	}
}
package topic;

import com.rabbitmq.client.*;
import helloworld.utils.RabbitMqUtils;

import java.io.IOException;

/**
 * [一句话描述该类的功能]
 *
 * @author : [xupeng]
 * @version : [v1.0]
 * @createTime : [2021/7/7 11:52]
 */
public class Consumer2 {
	public static void main(String[] args) throws IOException, IOException {
		//通过工具类获取连接对象
		Connection connection = RabbitMqUtils.getConnection();

		//获取连接中的通道
		final Channel channel = connection.createChannel();

		String exchangeName = "topics";

		//通道声明交换机以及交换的类型
		channel.exchangeDeclare(exchangeName, "topic");

		//创建一个临时队列
		String queue = channel.queueDeclare().getQueue();

		//基于routingKey绑定队列和交换机
		//参数1:队列名
		//参数2:交换机名
		//参数3:routingKey
		channel.queueBind(queue, exchangeName, "user.#");

		//获取消费的消息
		channel.basicConsume(queue, true, 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));
			}
		});


	}
}

测试:

七、打赏请求

如果本篇博客对您有所帮助,打赏一点呗,谢谢了呢~

猜你喜欢

转载自blog.csdn.net/qq_40594696/article/details/117917498
MQ