消息发送模式实战之普通队列模式与工作队列模式
1. 前言
Hello,大家好。在上述小节中,我们对 RabbitMQ 中的发布订阅消息发送模式的实战内容进行了介绍,并针对不同的业务场景进行了代码实现。在本小节中,我们将对 RabbitMQ 中消息发送模式的最后两种模式的实战内容进行介绍。
本小节会介绍 RabbitMQ 中最后的两种消息发送模式的实战部分,包括普通队列模式的基础概念回顾与代码实现,以及工作队列模式的基础概念回顾与代码实现,在将这两部分的实战内容介绍完毕之后,RabbitMQ 中所有的消息发送模式中的实战内容就全部介绍完毕了。
本节主要内容:
-
普通队列模式与工作队列模式基础概念回顾;
-
普通队列模式与工作队列模式代码实操。
2.普通队列模式与工作队列模式基础概念回顾
在我们正式开始使用代码进行实战之前,让我们先来回顾一下普通队列模式与工作队列模式的基础概念等相关内容。
2.1 普通队列模式基础概念回顾
定义:
普通队列模式,即最简单的消息发送模式,不使用任何交换机,由生产者、队列、消费者组合完成消息的发送和接收。
描述:
普通队列模式,由于其操作简单,所以又被称为简单模式,如下图所示:
普通队列模式,在生产者生产完消息之后,直接将消息发送到队列中去,不经过交换机进行处理,然后由消费者直从消息队列中获取消息并消费。在这个过程中间,没有我们需要特别注意的地方。
2.2 工作队列模式基础概念回顾
定义:
工作队列模式,和普通队列模式有点像,都是不使用任何交换机,由生产者、队列、消费者组合完成消息的发送和接收,只不过工作队列支持存在多个消费者,而普通队列模式只支持一个消费者。
描述:
工作队列模式下,生产者生产出消息后,直接将消息发送到消息队列中,然后多个消费者按照一个随机的顺序来依次获取消息并消费。
存在多个消费者消费消息时,下一个消费者只能等待上一个消费者消费结束后才能获取到消息并进行消费。
这就提示我们,在实际工作中,我们可以把费时的业务操作交给 RabbitMQ 去做,这样可以提升代码的执行效率。
Tips:
1. 无论是普通队列模式,还是工作队列模式,其操作相对来说都比较简单,适合很简单的业务场景,同时,初学者更易于理解。
2. 工作队列模式和发布订阅模式的功能很相似,都是用于消息需要进行群发的场景,对于这两种模式,我们在实际工作中应该仔细斟酌,到底使用哪种消息发送模式最合适。
3 普通队列模式与工作队列模式
3.1 普通队列模式代码实操
在回顾完普通队列模式的基础概念之后,让我们来看一下如何使用代码来实现这种普通队列模式:
实现代码:
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.0.1");
connectionFactory.setPort(5672);
connectionFactory.setUsername("guest");
connectionFactory.setPassword("guest");
Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
channel.close();
connection.close();
代码解释:
第 1-5 行,我们使用了 RabbitMQ 的 ConnectionFactory 连接工厂,来初始化了一些获取 RabbitMQ 连接的必要参数。
第 6 行,我们从 RabbitMQ 的连接工厂中,获取到了一个 RabbitMQ Conneciton 连接实例。
第 7 行,我们通过 RabbitMQ 连接实例,创建了一个 channel 通道,为之后的消息通信提供媒介。
第 8 行,我们使用 channel 的 queueDeclare 方法,来声明一个消息队列,并绑定到我们的 channel 频道上。
第 9-10 行,在处理完通道与连接实例之后,我们分别调用了 close 方法,将建立的通信连接和通道进行关闭,以节省资源开销。
由于普通队列模式不需要交换机的参与,只需要一个生产者、一个消费者,还有一个消息队列,即可完成,这就是普通队列模式。
3.2 工作队列模式代码实操
我们来看工作队列模式的代码实现:
实现代码:
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.0.1");
connectionFactory.setPort(5672);
connectionFactory.setUsername("guest");
connectionFactory.setPassword("guest");
Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel();
Consumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties,byte[] body) throws IOException {
String msg = new String(body, "UTF-8");
// 业务处理
}
};
channel.basicConsume(QUEUE_NAME, true, consumer);
channel.close();
connection.close();
代码解释:
第 1-7 行,代码和第一种业务场景相似,这里不再赘述。
第 8-16 行,我们通过使用 new DefaultConsumer 匿名内部类的形式,来依次从消息队列中获取消息,在获取到消息之后,我们可以再 handleDevelivery 方法中处理我们的业务逻辑。
第 17 行,我们使用 channel 的 basicConsume 方法来将我们获取到的消息进行一个消费。
事实上,我们应该使用 for 循环,或者动态获取的方式,来指定我们工作队列模式中,所需要的消费者数量,这样我们才能实现一种没有交换机的消息群发模式,这就是工作队列模式。
Tips: 我们可以发现,在实现普通队列模式和工作队列模式时,我们并没有指定 Routing Key ,因为这两种消息发送模式不需要指定,这里需要同学们注意。
4. 小结
本小节为同学们详细介绍了 RabbitMQ 消息发送模式之普通队列模式和工作队列模式的代码实操等内容,包括普通队列模式和工作队列模式基础概念等内容的回顾,以及普通队列模式和工作队列模式的代码实现,同学们需要理清代码实现的思路和步骤。
写到这里,我们对 RabbitMQ 中常见的 5 种消息发送模式的实战内容部分就全部介绍完毕了,在实际工作中,我们需要结合具体的业务场景,以及我们这些消息发送模式的基础概念去筛选合适的消息发送模式,来完成我们的需求,这并不是一个随便选择的过程。