锋盈数科-知识库 Logo
首页
软件开发
计算机基础
Hello Halo
新手必读
关于本知识库
登录 →
锋盈数科-知识库 Logo
首页 软件开发 计算机基础 Hello Halo 新手必读 关于本知识库
登录
  1. 首页
  2. 软件开发
  3. JAVA
  4. RabbitMQ的五种常见消费模型

RabbitMQ的五种常见消费模型

0
  • JAVA
  • 发布于 2024-08-06
  • 2 次阅读
黄健
黄健

原文链接:https://blog.csdn.net/qq_54796785/article/details/133580623

引言

RabbitMQ是一个流行的消息队列中间件,它确保了不同应用程序之间的可靠消息传递。由于其高性能、轻量级和灵活性,RabbitMQ在许多应用程序中被广泛使用,例如异步任务处理、负载均衡、事件通知 等。在RabbitMQ中,消息的生产和消费是通过一系列的消费模型来管理的。每个消费模型都有不同的特点和应用场景,可以帮助开发人员构建高效的消息传递系统。本文将深入介绍RabbitMQ的五种常见消费模型,包括简单队列模型、工作队列模型、发布/订阅模型、路由模型和主题模型,删除线格式 并探讨它们各自的优缺点和适用场景。希望此文能帮助你更好地理解RabbitMQ消费模型并在实践中达到更好的效果。

1. 简单队列模型(Simple Queue Model)

简单队列模型是最基础的RabbitMQ模型。它包括单个生产者和单个消费者。生产者将消息发送到一个队列中,然后消费者从队列中读取消息并处理。这种模式不适用于多个消费者或消息广播,因为一旦消息被一个消费者接收,它就会从队列中删除。

优缺点及适用场景

优点:

实现简单,易于理解和部署。

可以提供一些基本的可靠性保证,例如消息确认和持久化。

缺点:

不支持并发消费。

不支持多个消费者共同消费一个队列。

适用场景:

单生产者和单消费者之间的点对点通信。

系统中只有一个进程或线程可以处理消息。

例如,一个后端服务向另一个后端服务发送消息,或者一个客户端将任务发送给服务器

代码示例

Connection connection = factory.newConnection();

Channel channel = connection.createChannel();

// 声明队列

String queueName = "simpleQueue";

channel.queueDeclare(queueName, false, false, false, null);

// 发送消息

String message = "Hello, RabbitMQ!";

channel.basicPublish("", queueName, null, message.getBytes("UTF-8"));

System.out.println("Sent message: " + message);

// 接收消息

boolean autoAck = true;

Consumer consumer = new DefaultConsumer(channel) {

    @Override

    public void handleDelivery(String consumerTag, Envelope envelope,

                               AMQP.BasicProperties properties, byte[] body) throws IOException {

        String message = new String(body, "UTF-8");

        System.out.println("Received message: " + message);

    }

};

channel.basicConsume(queueName, autoAck, consumer);

2. 工作队列模型(Work Queue Model)

工作队列模型允许多个消费者协同地从一个队列中接收、处理和分发消息。在这种模型中,消息被平均分配给不同的消费者。当一个消费者正在处理一个消息时,它不能接收新的消息。这确保了公平的分布和消费,同时在不同的消费者之间进行负载均衡。

优缺点及适用场景

优点:

支持多个消费者处理同一个队列中的消息。

消费负载均衡,每个消费者最多处理一条消息。

通过设置并发数,可以实现更高的消息吞吐量。

缺点:

没有消息路由的动态性。

如果有消息时,所有的消费者都会在接收到该消息后进行同样的处理,无法根据具体情况进行消息的划分,而且消息被平均分配,不能根据消息的重要性和紧急性进行处理。

适用场景:

需要在多个工人之间分配任务的应用程序,例如异步任务处理或负载均衡。

代码示例

// 创建连接和通道

Connection connection = factory.newConnection();

Channel channel = connection.createChannel();

// 声明队列

String queueName = "workQueue";

channel.queueDeclare(queueName, false, false, false, null);

// 发送消息

String message = "Hello, RabbitMQ!";

channel.basicPublish("", queueName, null, message.getBytes("UTF-8"));

System.out.println("Sent message: " + message);

// 设置每个消费者在接收到确认前只能处理一条消息

channel.basicQos(1);

// 接收消息

boolean autoAck = false;

Consumer consumer = new DefaultConsumer(channel) {

    @Override

    public void handleDelivery(String consumerTag, Envelope envelope,

                               AMQP.BasicProperties properties, byte[] body) throws IOException {

        String message = new String(body, "UTF-8");

        System.out.println("Received message: " + message);

        // 手动发送消息确认

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

    }

};

channel.basicConsume(queueName, autoAck, consumer);

3. 发布/订阅模型(Publish/Subscribe Model)

发布/订阅模型允许一个生产者向多个消费者广播一条消息。在这种模型中,生产者将消息发送到一个交换机中,然后这个交换机将消息路由到所有与之绑定的队列。每个队列对应一个消费者,可以独立地处理这个队列中的消息。

优缺点及适用场景

优点:

支持广播式消息发布和订阅。

与其他应用程序解耦,生产者和消费者不需要知道对方的存在和细节。

缺点:

不支持消息路由的动态性。

没有消息过滤机制,每个订阅者都会收到所有的消息。

适用场景:

需要将消息通知多个消费者的应用程序,例如事件通知或新闻发布。

代码示例

// 创建连接和通道

Connection connection = factory.newConnection();

Channel channel = connection.createChannel();

// 声明交换器

String exchangeName = "publishSubscribeExchange";

channel.exchangeDeclare(exchangeName, "fanout");

// 创建随机队列并绑定到交换器

String queueName = channel.queueDeclare().getQueue();

channel.queueBind(queueName, exchangeName, "");

// 发送消息

String message = "Hello, RabbitMQ!";

channel.basicPublish(exchangeName, "", null, message.getBytes("UTF-8"));

System.out.println("Sent message: " + message);

// 接收消息

boolean autoAck = true;

Consumer consumer = new DefaultConsumer(channel) {

    @Override

    public void handleDelivery(String consumerTag, Envelope envelope,

                               AMQP.BasicProperties properties, byte[] body) throws IOException {

        String message = new String(body, "UTF-8");

        System.out.println("Received message: " + message);

    }

};

channel.basicConsume(queueName, autoAck, consumer);

4. 路由模型(Routing Model)

路由模型允许生产者根据路由键将消息发送到指定的队列中。在这种模型中,交换机会将消息路由到与它所绑定的队列匹配的路由键的队列中。消费者可以从这些队列中接收和处理消息。

优缺点及适用场景

优点:

支持基于路由键的动态消息路由。

可以根据消息的类型、内容和优先级选择发送给哪个队列,支持消息的定向投递。

缺点:

需要提前配置好交换机和队列之间的绑定关系。

支持的路由逻辑有限,只能通过路由键进行匹配。

适用场景:

需要根据某些特定属性或条件将消息路由到相应队列的应用程序,例如日志记录或按优先级处理任务。

代码示例

// 创建连接和通道

Connection connection = factory.newConnection();

Channel channel = connection.createChannel();

// 声明交换器

String exchangeName = "routingExchange";

channel.exchangeDeclare(exchangeName, "direct");

// 绑定队列到交换器,并指定路由键

String queueName = "routingQueue";

String routingKey = "important";

channel.queueDeclare(queueName, false, false, false, null);

channel.queueBind(queueName, exchangeName, routingKey);

// 发送消息

String message = "Important message!";

channel.basicPublish(exchangeName, routingKey, null, message.getBytes("UTF-8"));

System.out.println("Sent message: " + message);

// 接收消息

boolean autoAck = true;

Consumer consumer = new DefaultConsumer(channel) {

    @Override

    public void handleDelivery(String consumerTag, Envelope envelope,

                               AMQP.BasicProperties properties, byte[] body) throws IOException {

        String message = new String(body, "UTF-8");

        System.out.println("Received message: " + message);

    }

};

channel.basicConsume(queueName, autoAck, consumer);

5. 主题模型(Topic Model)

主题模型是路由模型的扩展,它可以实现更灵活的消息路由和分发。在这种模型中,生产者可以使用通配符匹配来匹配路由键。交换机会将消息路由到与它所绑定的队列匹配的路由键的队列中。消费者可以从这些队列中接收和处理消息。

优缺点及适用场景

优点:

支持更灵活、更具体的消息路由和过滤。

可以使用通配符匹配路由键,实现更复杂的消息匹配和分发。

缺点:

高度配置化和复杂化,需要额外配置主题模式下的应用程序逻辑。

在一些场景下,通配符匹配路由键可能会导致性能问题。

适用场景:

需要根据消息内容的模式将消息路由到不同队列的应用程序,例如按标签或关键字分发和处理不同的任务。

代码示例

// 创建连接和通道

Connection connection = factory.newConnection();

Channel channel = connection.createChannel();

// 声明交换器

String exchangeName = "topicExchange";

channel.exchangeDeclare(exchangeName, "topic");

// 绑定队列到交换器,并指定匹配模式

String queueName = "topicQueue";

String routingKeyPattern = "com.example.*";

channel.queueDeclare(queueName, false, false, false, null);

channel.queueBind(queueName, exchangeName, routingKeyPattern);

// 发送消息

String routingKey = "com.example.news";

String message = "Important news!";

channel.basicPublish(exchangeName, routingKey, null, message.getBytes("UTF-8"));

System.out.println("Sent message: " + message);

// 接收消息

boolean autoAck = true;

Consumer consumer = new DefaultConsumer(channel) {

    @Override

    public void handleDelivery(String consumerTag, Envelope envelope,

                               AMQP.BasicProperties properties, byte[] body) throws IOException {

        String message = new String(body, "UTF-8");

        System.out.println("Received message: " + message);

    }

};

channel.basicConsume(queueName, autoAck, consumer);

总的来说,不同的消息队列模型适用于不同的场景和需求。简单队列模型适合于点对点通信;工作队列模型适用于任务分配和负载均衡;发布/订阅模型适用于消息广播和解耦;路由模型适用于动态消息路由和选择性投递;主题模型适用于灵活的消息路由和过滤。根据具体的业务需求和系统架构,合理选择适用的消息队列模型可以提高系统的可扩展性、可靠性和性能。

标签: #JAVA 991
相关文章

Spring 实现 3 种异步接口 2024-10-18 09:07

大家好,我是苏三~ 如何处理比较耗时的接口? 这题我熟,直接上异步接口,使用 Callable、WebAsyncTask 和 DeferredResult、CompletableFuture等均可实现。 但这些方法有局限性,处理结果仅返回单个值。在某些场景下,如果需要接口异步处理的同时,还持续不断地

重学SpringBoot3-集成Redis(五)之布隆过滤器 2024-10-08 11:24

更多SpringBoot3内容请关注我的专栏:《SpringBoot3》 期待您的点赞👍收藏⭐评论✍ 重学SpringBoot3-集成Redis(五)之布隆过滤器 1. 什么是布隆过滤器? * 基本概念 适用场景 2. 使用 Redis 实现布隆过滤器 * 项目依赖 Redis 配置

SpringBoot整合异步任务执行 2024-10-08 11:24

同步任务: 同步任务是在单线程中按顺序执行,每次只有一个任务在执行,不会引发线程安全和数据一致性等 并发问题 同步任务需要等待任务执行完成后才能执行下一个任务,无法同时处理多个任务,响应慢,影响用 户体验 异步任务: 异步任务是在多线程中同时执行,多个任务可以并发执行,同时处理多个请求,响应快,资源

springboot kafka多数据源,通过配置动态加载发送者和消费者 2024-10-08 11:24

前言 最近做项目,需要支持kafka多数据源,实际上我们也可以通过代码固定写死多套kafka集群逻辑,但是如果需要不修改代码扩展呢,因为kafka本身不处理额外逻辑,只是起到削峰,和数据的传递,那么就需要对架构做一定的设计了。 准备test kafka本身非常容易上手,如果我们需要单元测试,引入ja

SpringBoot 集成 Redis 2024-10-08 11:24

一:SpringBoot 集成 Redis ①Redis是一个 NoSQL(not only)数据库, 常作用缓存 Cache 使用。 ②Redis是一个中间件、是一个独立的服务器;常用的数据类型: string , hash ,set ,zset , list ③通过Redis客户端可以使用多种语

SpringBoot整合QQ邮箱 2024-10-08 11:24

SpringBoot可以通过导入依赖的方式集成多种技术,这当然少不了我们常用的邮箱,现在本章演示SpringBoot整合QQ邮箱发送邮件…. 下面按步骤进行: 1.获取QQ邮箱授权码 1.1 登录QQ邮箱 1.2 开启SMTP服务 找到下图中的SMTP服务区域,如果当前账号未开启的话自己手动开启。

目录

IT 外包服务商

  • 意见投递
  • zyf6619

软件开发应用

主菜单

  • 首页
  • 软件开发
  • 计算机基础
  • Hello Halo
  • 新手必读
  • 关于本知识库
Copyright © 2024 your company All Rights Reserved. Powered by Halo.