RabbitMQ 2023面试5题(四)

news2024/9/28 9:22:57

一、RabbitMQ有哪些作用

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

  1. 实现应用程序之间的异步和解耦:通过使用消息队列,应用程序可以通过读写消息来实现通信,无需直接调用彼此,从而减少了对彼此的直接依赖。
    在这里插入图片描述

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

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

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

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

  6. 流量控制:通过使用消息队列,将用户请求写入消息队列,按规则读取请求
    在这里插入图片描述

总的来说,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根据指定的路由规则将消息路由到相应的队列中,这个规则可以是基于消息内容的,也可以是基于其他属性的。

五、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层的协议标准;天然具有跨平、跨语言特性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/688274.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[Africa battleCTF 2023 prequal] CPR部分

非州的比赛&#xff0c;说是总体简单&#xff0c;但也有几个难题0解&#xff0c;估计依然是等不到WP。 这个界面还挺好&#xff0c;除了慢以外没大问题。 Rev SEYI 题目很简单&#xff0c;程序报病毒&#xff0c;win11上的defender关上不容易呀。我的电脑怎么就不能听我的呢…

【Java高级语法】(十八)Optional类:解锁Java的Optional魔法:消灭那些隐匿的空指针,还程序世界一个安稳!~

Java高级语法详解之Optional类 1️⃣ 概念2️⃣ 优势和缺点3️⃣ 使用3.1 常用操作API3.2 案例3.3 使用技巧 4️⃣ 应用场景5️⃣ 实现原理&#x1f33e; 总结 1️⃣ 概念 Optional类是Java 8引入的新特性&#xff0c;旨在解决空值&#xff08;null&#xff09;的处理问题。它…

ProtoBuf介绍与使用

文章目录 1、ProtoBuf概述2、下载和安装3、简单使用 1、ProtoBuf概述 Protobuf&#xff08;Protocol Buffers&#xff09;是由Google开发的一种语言无关的数据序列化格式。它旨在将结构化数据&#xff08;如结构化消息或文档&#xff09;高效地序列化为紧凑的二进制表示&#…

python GUI工具之PyQt5模块,pyCharm 配置PyQt5可视化窗口

https://doc.qt.io/qt-5/qtwidgets-module.html https://doc.qt.io/qt-5/qt.html#AlignmentFlag-enum 一、简介 PyQt是Qt框架的Python语言实现&#xff0c;由Riverbank Computing开发&#xff0c;是最强大的GUI库之一。PyQt提供了一个设计良好的窗口控件集合&#xff0c;每一…

【跑实验06】os包的理解?如何提取图片的名称?如何遍历一个文件夹,提取里面的图像名称?如何提取图片名称中的特定部分?代码错误地方修改;

文章目录 一、os包的理解1.1 文件和目录操作1.2 进程管理1.3 环境变量1.4 路径操作 二、如何提取图片的名称&#xff1f;三、遍历一个文件夹&#xff0c;提取里面的图像名称四、如何提取图片名称中的特定部分&#xff1f;五、代码报错修改 一、os包的理解 os 是 Python 中的一…

大厂OKR管理法:公开透明是最大特点

大厂OKR管理法&#xff1a;公开透明是最大的特点 仔细想&#xff0c;这是一件破天荒的事情 企业内部大部分的任务“公开透明” 公开透明会减少巨大的沟通成本 每个人的关键任务几乎是全部公开 估计少数的财务、人事、公关方面的不会 趣讲大白话&#xff1a;公开透明损耗少 【趣…

【UE 从零开始制作坦克】12-制作全自动机枪炮塔

效果 步骤 1. 下载模型和材质&#xff08;链接&#xff1a;https://download.csdn.net/download/ChaoChao66666/87951079&#xff09; 2. 将下载好的文件夹拖入UE工程中 首先点击“重置为默认”&#xff0c;然后勾选“合并网格体”&#xff0c;最后点击“导入所有” 导入后资源…

YOLOv5、YOLOv7独家原创改进:独家首发最新原创XIoU_NMS改进点,改进有效可以直接当做自己的原创改进点来写,提升网络模型性能、收敛速度和鲁棒性

💡该教程为属于《芒果书》📚系列,包含大量的原创首发改进方式, 所有文章都是全网首发原创改进内容🚀 💡本篇文章为YOLOv5、YOLOv7独家原创改进:独家首发最新原创XIoU_NMS改进点,改进有效可以直接当做自己的原创改进点来写,提升网络模型性能、收敛速度和鲁棒性。 �…

【Java】Java数组链表类详记

本文仅供学习参考&#xff01; 相关文章地址&#xff1a; https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html https://www.w3schools.com/java/java_arraylist.asp https://www.runoob.com/java/java-arraylist.html Java ArrayList 基础知识 ArrayList是 …

SpringSecurity-尚硅谷

前置知识 掌握Spring框架掌握SpringBoot使用掌握JavaWEB技术 文章目录 前置知识1. 简介1.1 概要1.2 历史 2.入门案例2.1 创建一个项目2.1.1 pom.xml2.1.2 controller层 2.2 运行这个项目2.32.4 SpringSecurity 基本原理2.5 UserDetailsService 接口讲解2.6 PasswordEncoder 接…

AI黑客松近期比赛清单;36氪AI淘宝店盈利复盘;GitHub Copilot官方最佳实践;AI在HR领域的应用探索 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; ⋙ 点击查看 AI Hackathon (黑客马拉松) 汇总清单 &#x1f916; 〖飞桨〗2023大模型应用创新挑战赛 百度飞桨联合上海市青年五十人创新创业研究院等…

【软件测试】推荐几款适合练手的项目

最近收到许多自学自动化测试的小伙伴私信&#xff0c;学习了理论知识后&#xff0c;却没有合适的练手项目。 测试本身是一个技术岗位&#xff0c;如果只知道理论&#xff0c;没有实战经验&#xff0c;在面试中很难说服面试官&#xff0c;比如什么场景下需要添加显示等待&#x…

CentOs7 安装jdk8详细教程

方法一&#xff1a;gz安装包安装&#xff08;推荐&#xff09; 1.下载所需版本的.tar.gz安装包 Oracle官网即可下载&#xff0c;选择好对应版本&#xff0c;可以先下到主机&#xff0c;然后上传到虚拟机的Linux上。&#xff08;注意&#xff1a;Oracle现在下载jdk需要注册登录…

OAuth2.0与单点登录的区别

本文说下OAuth2.0与单点登录的区别 文章目录 概述什么是单点登录单点登录和Oauth2.0的区别单点登录的实现本文小结 概述 SSO是Single Sign On的缩写&#xff0c;OAuth是Open Authority的缩写&#xff0c;这两者都是使用令牌的方式来代替用户密码访问应用。流程上来说他们非常相…

解决联网时自动打开浏览器转到必应msn网址的问题

现象 开机后或者断网重连之后&#xff0c;系统自动打开默认浏览器&#xff08;不管是IE还是谷歌&#xff0c;或其他的浏览器&#xff09;网址为http://go.microsoft.com/fwlink/?LinkID219472&clcid0x409接着转到http://cn.bing.com/ 或者 https://www.msn.com/ 解决方法…

Kafka系列 - kafka 副本|AR|ISR|OSR|Leader|Follower|HW|LEO

文章目录 01. kafka 副本信息02. kafka 中 ISR、AR和OSR代表什么&#xff1f;03. kafka 中 ISR的伸缩指什么&#xff1f;04. 什么情况下一个broker会从ISR中踢出去&#xff1f;05. kafka 副本和ISR扮演什么角色&#xff1f;06. kafka 副本长时间不在ISR中&#xff0c;意味着什么…

buuctf re(二)+ web CheckIn

目录 re xor helloword reverse3 web SUCTF 2019 CheckIn xor 1.查壳 64位&#xff0c;无壳 2.ida&#xff0c;f5查看伪代码 3.跟进global dq是八个字节&#xff0c;汇编数据类型参考汇编语言---基本数据类型_汇编db类型_wwb0111的博客-CSDN博客 4.因为global变量里有一…

多商户商城有哪些功能和优势?-加速度jsudo

电商时代下&#xff0c;传统企业商家急需拓展业务规模&#xff0c;向线上拓展&#xff0c;而多商户小程序造价低&#xff0c;效应高&#xff0c;自然就成为了很多企业商家拓展线上营销渠道的首要选择,那么多商户小程序商城涵盖哪些功能呢?下面小编就来详细为大家解答&#xff…

UE5《Electric Dreams》项目PCG技术解析 之 理解Assembly(以SplineExample为例)

文章目录 1. 什么是Assembly2. PCG部分2.1 Assembly变换2.2 Point变换2.2.1. SG_CopyPointsWithHierachy2.2.2 过滤及点变换2.2.3. ApplyHierachy 3. 小结 1. 什么是Assembly UE5.2的PCG出了有一段时间了&#xff0c;大家玩得都很开心。很多朋友可能和老王一样&#xff0c;使用…

Rust语言从入门到入坑——(10)文件与IO

文章目录 0、引入1、命令行1.1 命令行参数1.2 命令行输入 2、文件操作2.1 读取文件2.2 写入文件 3、总结 0、引入 Rust 语言的 I/O 操作&#xff0c;最基本的交互模式&#xff0c;主流语言都具备的功能。 1、命令行 1.1 命令行参数 命令行程序是计算机程序最基础的存在形式&…