RabbitMQ 2023面试5题(四)

这篇具有很好参考价值的文章主要介绍了RabbitMQ 2023面试5题(四)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、RabbitMQ有哪些作用

RabbitMQ是一个消息队列中间件,它的作用是利用高效可靠的消息传递机制进行与平台无关的数据交流,并基于数据通信来进行的分布式系统的集成,主要作用有以下方面:

  1. 实现应用程序之间的异步和解耦:通过使用消息队列,应用程序可以通过读写消息来实现通信,无需直接调用彼此,从而减少了对彼此的直接依赖。
    RabbitMQ 2023面试5题(四)

  2. 提供基本的最终一致性实现:RabbitMQ可以帮助实现面向服务的架构(SOA),通过消息队列来通信,从而实现不同服务之间的解耦,并确保最终一致性。

  3. 实现消息的缓冲和分发:RabbitMQ可以接收并存储大量消息,直到消费者准备好处理它们,从而避免消费者因为数据量过大而无法及时处理消息的情况。

  4. 支持分布式系统中的事务支持:通过使用消息队列,可以在分布式系统中实现事务的协调和通信。

  5. 实现RPC调用:通过使用消息队列,可以在分布式系统中实现RPC调用,从而实现不同服务之间的通信。

  6. 流量控制:通过使用消息队列,将用户请求写入消息队列,按规则读取请求
    RabbitMQ 2023面试5题(四)

总的来说,RabbitMQ可以帮助应用程序之间实现解耦、缓冲和分发消息,提供最终一致性实现,支持分布式系统中的事务支持和RPC调用。

二、请列举一个RabbitMQ异步消息处理案例

假设有一个电商系统,包含多个子系统,如订单系统、支付系统、物流系统等。这些子系统之间需要进行高效的通信和协作,才能完成整个电商交易过程。

其中一个典型的场景是,当用户在电商网站上下单后,订单系统需要异步将订单信息发送给支付系统和物流系统,以便它们能够及时处理用户的支付和物流需求。

在这种情况下,可以使用RabbitMQ来实现异步消息处理。具体流程如下:

  1. 订单系统创建一个订单后,将订单信息发送到RabbitMQ消息队列中。
  2. 支付系统和物流系统分别订阅该消息队列,并异步处理订单信息。
  3. 支付系统收到订单信息后,会进行支付处理,并将支付结果发送到RabbitMQ消息队列中。
  4. 物流系统收到订单信息后,会进行物流处理,并将物流结果发送到RabbitMQ消息队列中。
  5. 订单系统异步收到支付系统和物流系统的处理结果后,会将订单状态更新为完成或失败,并返回给用户处理结果。

模拟代码:

import com.rabbitmq.client.*;  
  
import java.io.IOException;  
import java.util.concurrent.TimeoutException;  
  
public class RabbitMQExample {  
  
    private final static String ORDER_QUEUE_NAME = "orders";  
    private final static String PAYMENT_QUEUE_NAME = "payments";  
    private final static String SHIPMENT_QUEUE_NAME = "shipments";  
  
    public static void main(String[] args) throws IOException, TimeoutException {  
        // 创建连接工厂并设置参数  
        ConnectionFactory factory = new ConnectionFactory();  
        factory.setHost("localhost");  
        factory.setUsername("guest");  
        factory.setPassword("guest");  
  
        // 创建连接和通道  
        Connection connection = factory.newConnection();  
        Channel channel = connection.createChannel();  
  
        // 声明队列  
        channel.queueDeclare(ORDER_QUEUE_NAME, false, false, false, null);  
        channel.queueDeclare(PAYMENT_QUEUE_NAME, false, false, false, null);  
        channel.queueDeclare(SHIPMENT_QUEUE_NAME, false, false, false, null);  
  
        // 发送订单消息  
        String orderMessage = "New order created";  
        channel.basicPublish("", ORDER_QUEUE_NAME, null, orderMessage.getBytes("UTF-8"));  
        System.out.println(" [x] Sent order message: " + orderMessage);  
  
        // 发送支付消息  
        String paymentMessage = "Payment received";  
        channel.basicPublish("", PAYMENT_QUEUE_NAME, null, paymentMessage.getBytes("UTF-8"));  
        System.out.println(" [x] Sent payment message: " + paymentMessage);  
  
        // 发送物流消息  
        String shipmentMessage = "Shipment sent";  
        channel.basicPublish("", SHIPMENT_QUEUE_NAME, null, shipmentMessage.getBytes("UTF-8"));  
        System.out.println(" [x] Sent shipment message: " + shipmentMessage);  
  
        // 关闭连接和通道  
        channel.close();  
        connection.close();  
    }  
  
    // 订单处理函数  
    public static void processOrder(String message) {  
        System.out.println(" [x] Processing order: " + message);  
    }  
  
    // 支付处理函数  
    public static void processPayment(String message) {  
        System.out.println(" [x] Processing payment: " + message);  
    }  
  
    // 物流处理函数  
    public static void processShipment(String message) {  
        System.out.println(" [x] Processing shipment: " + message);  
    }  
  
    // 订阅消息并异步处理  
    public static void subscribeToMessages(String queueName) throws IOException, TimeoutException {  
        // 创建连接工厂并设置参数  
        ConnectionFactory factory = new ConnectionFactory();  
        factory.setHost("localhost");  
        factory.setUsername("guest");  
        factory.setPassword("guest");  
  
        // 创建连接和通道  
        Connection connection = factory.newConnection();  
        Channel channel = connection.createChannel();  
  
        // 声明队列  
        channel.queueDeclare(queueName, false, false, false, null);  
        System.out.println(" [*] Waiting for messages. To exit press CTRL+C");  
  
        // 创建消费者并订阅队列  
        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");  
                if (queueName.equals(ORDER_QUEUE_NAME)) {  
                    processOrder(message);  
                } else if (queueName.equals(PAYMENT_QUEUE_NAME)) {  
                    processPayment(message);  
                } else if (queueName.equals(SHIPMENT_QUEUE_NAME)) {  
                    processShipment(message);  
                }  
            }  
        };  
        channel.basicConsume(queueName, true, consumer);  
    }  
}

三、Sprngboot如何使用RabbitMQ发送消息

代码示例:

  • 引入依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
  • 配置RabbitMQ连接信息
    在application.properties文件中添加以下配置:
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
  • 创建消息生产者
@Service
public class MessageProducer {  
    @Autowired
    private RabbitTemplate rabbitTemplate;    

    public void sendMessage(String message) {
        rabbitTemplate.convertAndSend("myQueue", message);
    }
}
  • 创建消息消费者
@Service
public class MessageConsumer implements MessageListener {    

    @Override
    public void onMessage(Message message) throws Exception {
        System.out.println("Received message: " + new String((byte[]) message.getBody()));
    }
}
  • 在启动类上添加@EnableRabbit注解,启用RabbitMQ自动配置。同时,将消息消费者注册到RabbitMQ队列中。
@SpringBootApplication
@EnableRabbit //启用RabbitMQ自动配置
public class Application implements CommandLineRunner {   

    @Autowired
    private MessageProducer messageProducer;    

    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class, args);
    }
}

四、RabbitMQ消息队列主要有多少种形式的目的地?

RabbitMQ消息队列主要有两种形式的目的地,分别是队列(Queue)和主题(Topic)。

  • 队列是点对点的消息容器,它只有一个发送者,但可以由多个消费者消费。发送者将消息发送到队列,消费者从队列中读取消息并进行处理。

  • 主题是一种发布/订阅模式的消息容器,它可以包含多个订阅者。发送者将消息发送到主题,订阅者订阅主题并接收消息。多个订阅者可以同时接收同一条消息,但每个订阅者只能接收到符合自己订阅规则的消息。

在RabbitMQ中,队列和主题都是通过exchange来进行路由的。exchange根据指定的路由规则将消息路由到相应的队列中,这个规则可以是基于消息内容的,也可以是基于其他属性的。文章来源地址https://www.toymoban.com/news/detail-502060.html

五、JMS(Java Message Service)JAVA消息服务与AMQP(Advanced Message Queuing Protocol)消息服务的区别有哪些?

  • JMS:基于JVM消息代理的规范。ActiveMQ、HornetMQ是JMS实现
  • AMQP:高级消息队列协议,也是一个消息代理的规范,兼容JMS,RabbitMQ是AMQP的实现
    具体区别:
JMS(Java Message Service) AMQP(Advanced Message Queuing Protocol)
定义 Java api 网络线级协议
跨语言 否i
跨平台
Model 提供两种消息模型:
(1)、Peer-2-Peer
(2)、Pub/sub
提供了五种消息模型:
(1)、direct exchange
(2)、fanout exchange
(3)、topic change
(4)、headers exchange
(5)、system exchange
本质来讲,后四种和JMS的pub/sub模型没有太大差别,
仅是在路由机制上做了更详细的划分;
支持消息类型 多种消息类型:
TextMessage
MapMessage
BytesMessage
StreamMessage
ObjectMessage
Message
(只有消息头和属性)
byte[]
当实际应用时,有复杂的消息,可以将消息序列化后发送。
综合评价 JMS 定义了JAVA API层面的标准;在java体系中,多个client均可以通过JMS进行交互,不需要应用修改代码,但是其对跨平台的支持较差; AMQP定义了wire-level层的协议标准;天然具有跨平、跨语言特性。

到了这里,关于RabbitMQ 2023面试5题(四)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【学习日记2023.6.19】 之 RabbitMQ服务异步通信_消息可靠性_死信交换机_惰性队列_MQ集群

    消息队列在使用过程中,面临着很多实际问题需要思考: 消息从发送,到消费者接收,会经历多个过程: 其中的每一步都可能导致消息丢失,常见的丢失原因包括: 发送时丢失: 生产者发送的消息未送达exchange 消息到达exchange后未到达queue MQ宕机,queue将消息丢失 consumer接收

    2024年02月11日
    浏览(60)
  • 分布式消息队列RabbitMQ-Linux下服务搭建,面试完腾讯我才发现这些知识点竟然没掌握全

    vim /usr/lib/rabbitmq/lib/rabbitmq_server-3.6.5/ebin/rabbit.app 5.修改配置文件 这里面修改{loopback_users, [“guest”]}改为{loopback_users, []} {application, rabbit, %% - - erlang - - [{description, “RabbitMQ”}, {id, “RabbitMQ”}, {vsn, “3.6.5”}, {modules, [‘background_gc’,‘delegate’,‘delegate_sup’,‘dtree’,‘file_han

    2024年04月14日
    浏览(56)
  • RabbitMQ实现延迟消息,RabbitMQ使用死信队列实现延迟消息,RabbitMQ延时队列插件

    假设有一个业务场景:超过30分钟未付款的订单自动关闭,这个功能应该怎么实现? RabbitMQ使用死信队列,可以实现消息的延迟接收。 队列有一个消息过期属性。就像丰巢超过24小时就收费一样,通过设置这个属性,超过了指定事件的消息将会被丢弃。 这个属性交:x-message

    2024年02月13日
    浏览(79)
  • RabbitMq消息模型-队列消息

    基本模型(SimpleQueue)、工作模型(WorkQueue) 队列消息特点: 消息不会丢失 并且 有先进先出的顺序。 消息接收是有顺序的,不是随机的,仅有一个消费者能拿到数据,而且不同消费者拿不到同一份数据。 基本模型: SimpleQueue 在上图的模型中,有以下几个概念: P:为生产

    2024年02月09日
    浏览(49)
  • 【RabbitMQ】消息队列-RabbitMQ篇章

    RabbitMQ是一个开源的 遵循AMQP协议 实现的基于Erlang语言编写,支持多种客户端(语言)。用于在分布式系统中 存储消息,转发消息 ,具有 高可用 , 高可扩性 , 易用性 等特征。 1.1、RabbitMQ—使用场景 一般场景 像一般的下订单业务如下图: 将订单信息写入数据库成功后,发

    2024年02月12日
    浏览(50)
  • 【RabbitMQ笔记10】消息队列RabbitMQ之死信队列的介绍

    这篇文章,主要介绍消息队列RabbitMQ之死信队列。 目录 一、RabbitMQ死信队列 1.1、什么是死信队列 1.2、设置过期时间TTL 1.3、配置死信交换机和死信队列(代码配置) (1)设置队列过期时间 (2)设置单条消息过期时间 (3)队列设置死信交换机 (4)配置的基本思路 1.4、配置

    2024年02月16日
    浏览(84)
  • 消息队列-RabbitMQ:延迟队列、rabbitmq 插件方式实现延迟队列、整合SpringBoot

    1、延迟队列概念 延时队列内部是有序的 , 最重要的特性 就体现在它的 延时属性 上,延时队列中的元素是希望在指定时间到了以后或之前取出和处理,简单来说, 延时队列就是用来存放需要在指定时间被处理的元素的队列。 延迟队列使用场景: 订单在十分钟之内未支付则

    2024年02月22日
    浏览(54)
  • RabbitMQ 消息中间件 消息队列

    RabbitMQ 1、RabbitMQ简介 RabbiMQ是⽤Erang开发的,集群⾮常⽅便,因为Erlang天⽣就是⼀⻔分布式语⾔,但其本身并 不⽀持负载均衡。支持高并发,支持可扩展。支持AJAX,持久化,用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。 2、RabbitMQ 特点 可

    2024年02月03日
    浏览(69)
  • 3.精通RabbitMQ—消息队列、RabbitMQ

    RabbitMQ面试题 (总结最全面的面试题) 入门RabbitMQ消息队列,看这篇文章就够了 消息队列 是一种基于 队列 ,用于解决 不同进程或应用 之间 通讯 的 消息中间件 。 支持多种 消息传递模式 ,如 队列模型 、 发布/订阅模型 等。 业务解耦 :通过 发布/订阅 模式,减少系统的 耦

    2024年02月15日
    浏览(79)
  • 消息队列-RabbitMQ:workQueues—工作队列、消息应答机制、RabbitMQ 持久化、不公平分发(能者多劳)

    Work Queues— 工作队列 (又称任务队列) 的主要思想是避免立即执行资源密集型任务,而不得不等待它完成 。 我们把任务封装为消息并将其发送到队列,在后台运行的工作进程将弹出任务并最终执行作业。当有多个工作线程时,这些工作线程将一起处理这些任务 。 轮训分发消

    2024年02月21日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包