Java高频面试之消息队列与分布式篇

有需要互关的小伙伴,关注一下,有关必回关,争取今年认证早日拿到博客专家

消息队列的基本作用?

  1. 异步通信:消息队列提供了异步通信的能力,发送方可以将消息发送到队列中,而无需等待接收方立即处理。发送方和接收方可以解耦,彼此不需要直接交互,从而实现解耦和异步处理。例如im
  2. 解耦应用程序:消息队列使得不同的应用程序之间可以通过消息进行通信,而不需要直接调用或知道对方的存在。每个应用程序只需关注自己的业务逻辑,将消息发送到队列中,由其他应用程序异步地处理这些消息。这样可以降低应用程序之间的依赖性,提高系统的可维护性和扩展性。
  3. 缓冲和削峰填谷:消息队列可以作为一个缓冲区,当生产者发送消息的速度快于消费者处理消息的速度时,消息可以暂时存储在队列中。这样可以平衡生产者和消费者之间的速度差异,避免系统的过载和性能问题。
  4. 数据分发:消息队列可以将消息广播给多个订阅者或消费者。这对于实现发布-订阅模式或者广播通知非常有用,一个消息可以同时被多个订阅者接收并处理。
  5. 重试和错误处理:消息队列可以处理消息传递过程中的错误情况。当消息发送失败时,消息队列可以自动进行重试,并保证消息的可靠传递。此外,可以将处理失败的消息放入死信队列中进行后续的错误处理和分析。
  6. 顺序性保证:某些消息队列支持按照特定的顺序发送和处理消息,确保消息的有序性。这对于需要按照特定顺序处理消息的场景非常重要,例如订单处理、事件日志等。

消息队列的基本作用是提供可靠、高效、异步的消息通信机制,实现系统之间的解耦、异步处理、削峰填谷、数据分发和错误处理等功能。它在分布式系统、微服务架构和大规模应用中发挥着重要的作用。

消息队列的优缺点有哪些?

优点:

  1. 异步通信:消息队列支持异步通信,发送方将消息发送到队列中,无需等待接收方的即时响应,提高了系统的并发处理能力和响应速度。
  2. 解耦应用程序:通过消息队列,应用程序之间的耦合度降低。每个应用程序只需关注自己的业务逻辑,通过发送和接收消息进行通信,从而提高了系统的可维护性和扩展性。
  3. 缓冲和削峰填谷:消息队列作为一个缓冲区,可以平衡生产者和消费者之间的速度差异,避免系统的过载和性能问题。它可以处理突发的请求量,实现削峰填谷的效果。
  4. 数据分发和广播:消息队列支持将消息广播给多个订阅者,实现发布-订阅模式,方便实现数据分发和广播通知。
  5. 可靠性和持久性:消息队列通常具有可靠的消息传递机制,可以确保消息的可靠性和持久性。即使在消息传递过程中出现故障,消息队列也可以保证消息的传递和处理。

缺点:

  1. 复杂性:使用消息队列需要引入额外的组件和技术,增加了系统的复杂性和维护成本。需要考虑消息的序列化、消息传递协议、消息队列的配置等问题。
  2. 一致性问题:由于消息队列的异步特性,消息的发送和处理可能存在一定的时间延迟,因此在一些场景下可能需要额外的机制来处理一致性问题。
  3. 部署和维护成本:引入消息队列需要部署和维护额外的中间件,涉及到部署、监控、故障排查等工作,增加了系统的运维成本和学习成本。
  4. 数据一致性和顺序性问题:某些消息队列无法保证消息的严格顺序性,对于一些场景需要保证严格顺序的消息处理可能会有一定挑战。
  5. 引入单点故障:消息队列本身可能成为系统中的单点故障,如果消息队列出现故障,会影响整个系统的正常运行。

在选择是否使用消息队列时,需要综合考虑系统的需求、复杂性和可靠性等因素,权衡利弊。消息队列在很多场景下是非常有用的,但也需要根据

如何保证消息队列的高可用?

  1. 集群部署:将消息队列部署在多台服务器上形成集群,通过负载均衡的方式将请求分发到不同的节点。这样可以提高系统的吞吐量和可用性,并且在某个节点故障时仍然能够正常提供服务。
  2. 数据复制和同步:对于主从架构的消息队列,需要将数据进行复制和同步,以实现数据的冗余备份和容错。在主节点写入消息后,通过数据同步机制将数据复制到备份节点,确保数据的可靠性和持久性。
  3. 故障自动转移:配置故障自动转移机制,当消息队列节点出现故障时,自动将请求转移到备份节点上,以保证服务的连续性。可以使用类似于主备切换、选举机制或者自动发现机制来实现故障转移。
  4. 监控和报警:建立监控系统,实时监测消息队列的运行状态、吞吐量、延迟等指标。设置报警机制,及时发现并处理潜在的问题,确保问题得到及时解决,提高可用性。
  5. 数据备份和恢复:定期对消息队列中的数据进行备份,确保在数据丢失或损坏的情况下能够进行数据恢复。备份数据可以存储在独立的存储介质或者其他节点上,以提供数据的冗余和可靠性。
  6. 消息队列监控和管理工具:使用专业的消息队列监控和管理工具,可以对消息队列进行实时监控、性能分析、故障排查和性能调优。这些工具提供了丰富的指标和图表,帮助管理员更好地了解系统状态并采取相应措施。
  7. 容量规划和水平扩展:根据系统的负载和需求进行容量规划,预估消息队列的并发请求量、存储容量等。当负载增加时,通过水平扩展的方式增加节点数量,以提供更好的性能和可用性。

通过以上策略的综合应用,可以提高消息队列的可用性,确保系统能够在故障情况下保持正常运行,并且具备数据的可靠性和持久性。根据具体的需求和系统架构,还可以采用其他高可用技术,如多活部署、数据分片等来进一步提高消息队列的可用性。

如何保证消息消费的幂等性?

其他问法:如何保证消息不被重复消费?

  1. 关系型数据库主键或唯一键+事务

    弊端:

    1. 性能问题(对整个消息消费逻辑加事务,如果消费逻辑太负责,再有数据库本身的性能并不是很高)
    2. 不支持事务的部分回滚(除了事务部分还调用了第三方系统,修改了redis)
  2. 拆解方案

    将没一步都做成幂等性的,例如库存系统减完库存后,发一条消息给订单系统对应的消息队列,订单系统单独实现幂等性,订单系统消费成功后给下游系统发消息队列,下游系统单独实现幂等性…

    缺点:麻烦

  3. 通用解决方案(去事务方案)

    1. 查询有没有消费(可以用关系型数据库,也可以用redis等)
    2. 记录状态
    3. 修改状态
    4. 通知消息队列消费成功了

dedupflow.png

需要考虑的三个问题

  1. 消息已经消费成功了,第二条消息将被直接幂等处理掉(消费成功)。
  2. 并发场景下的消息,依旧能满足不会出现消息重复,即穿透幂等挡板的问题。
  3. 支持上游业务生产者重发的业务重复的消息幂等问题。

为啥要加延迟消费?

​ 解决并发问题

为啥要加过期时间?

​ 防止第一条消息因为特殊原因消费失败(也没删掉),后续的延迟消费一直重试,最后进入死信队列

参考文章:https://jaskey.github.io/blog/2020/06/08/rocketmq-message-dedup/

https://github.com/Jaskey/RocketMQDedupListener

主要分两方面:一方面是生产者加一个唯一标识,两一方面消费者检查唯一标识,可以借助数据库的主键索引或者唯一键索引,缓存记录消费掉的消息,必要时添加回退机制,防止消费到一半时异常.

无论是何种消息队列,造成重复消费原因其实都是类似的。正常情况下,消费者在消费消息时候,消费完毕后,会发送一个确认信息给消息队列,消息队列就知道该消息被消费了,就会将该消息从消息队列中删除。
只是不同的消息队列发送的确认信息形式不同,例如RabbitMQ是发送一个ACK确认消息,RocketMQ是返回一个CONSUME_SUCCESS成功标志,kafka实际上有个offset的概念,每一个消息都有一个offset,kafka消费过消息后,需要提交offset,让消息队列知道自己已经消费过了。
那造成重复消费的原因? 就是因为网络传输等等故障,确认信息没有传送到消息队列,导致消息队列不知道自己已经消费过该消息了,再次将该消息分发给其他的消费者。
如何解决?这个问题针对业务场景来答分以下几点
(1)给这个消息做一个唯一主键,做数据库insert,如果出现重复消费情况,会导致主键冲突,避免数据库出现脏数据。
(2)update 和 delete 支持天然幂等性,拿到这个消息做redis的set的操作,那就容易了,不用解决,set操作天然幂等操作。
(3)第三方介质,来做消费记录。以redis为例,给消息分配一个全局id,只要消费过该消息,将<id,message>以K-V形式写入redis。那消费者开始消费前,先去redis中查询有没消费记录即可。

  1. 唯一标识符:为每个消息生成一个唯一的标识符,并将其与消息一起存储在消费端。在处理消息之前,先检查是否已经处理过具有相同标识符的消息,如果已经处理过,则直接跳过,避免重复处理。
  2. 幂等标识字段:在消息中添加一个幂等标识字段,用于标识消息的唯一性。消费端在处理消息时,先检查该字段的值,如果已经处理过具有相同标识字段值的消息,则跳过处理。
  3. 乐观锁:对于并发环境下的消息消费,可以使用乐观锁来保证幂等性。在消费端处理消息时,先获取并锁定消息的相关资源,然后再检查是否已经处理过。如果已经处理过,则直接释放资源,避免重复处理。
  4. 数据库约束:在消费端的数据库表中,可以添加唯一约束或者主键约束来保证数据的唯一性。当消费端尝试将消息写入数据库时,如果违反了约束条件,则表明消息已经被处理过,可以忽略该消息。
  5. 日志记录:在消费端处理消息时,记录消息的处理状态和结果。如果后续收到相同消息,可以先查询日志记录,判断是否已经处理过。
  6. 幂等性检查和处理:在消费端处理消息时,先进行幂等性检查。可以通过查询数据库、查看缓存状态或者调用特定接口来检查消息是否已经处理过。如果已经处理过,则直接返回成功,否则继续处理消息。
  7. 事务性操作:在消费端进行消息处理时,将消息处理过程放在一个事务中。通过使用数据库事务或者分布式事务,可以保证消息的处理是原子性的,即使在处理过程中出现异常或者重试,也能保证幂等性。

通过以上方法的应用,可以保证消息的消费是幂等的,即使在重复消费或者异常情况下,也能保证处理的结果是一致的。根据具体的业务场景和系统架构,可以选择合适的方式来实现消息消费的幂等性。

如何保证消息的可靠性传输?

其他问法:如何处理消息丢失的问题?

https://zhuanlan.zhihu.com/p/59759422

image.png

如何保证消息的顺序性?

乱序的原因之一:

Consumer从MQ里面读取数据是有序的,但是每个Consumer的执行时间是不固定的,无法保证先读到消息的Consumer一定先完成操作,这样就会出现消息并没有按照顺序执行,造成数据顺序错误。

rabbitmq

  1. 全局有序

    将所有消息发送到同一个队列里,队列只有一个消费者,预取值设置为1

    缺点:性能问题

  2. 局部有序

    多建几个队列

    讲需要保持顺序的一批数据发送到一个队列里面(例如根据订单号hash求模)

image.png

大量消息在 MQ 里长时间积压,该如何解决?

找原因:是生产者突增还是消费者故障?

如果消费者故障先修消费者

增加队列,增加消费者,快速消费

image.png

MQ 中的消息过期失效了怎么办?

查找原因:为什么过期了?过期时间设置的太短了?消费者端出问题了,导致消息挤压了?

如果消费者端出问题了先修复问题,然后查询过期的数据,找流量不高的时候导入

只能重新查询数据,手动灌入消息队列

RabbitMQ 有哪些重要的角色?

  1. 生产者

  2. 消费者

  3. 代理:就是RabbitMQ本身,用于扮演快递的角色,本身并不生产消息

RabbitMQ 有哪些重要的组件?

  1. ConnectionFactory(连接管理器):应用程序与RabbitMQ之间建立连接的管理器
  2. Channel(信道):消息推送使用的通道
  3. Exchange(交换器):用于接受、分配消息
  4. Queue(队列):用于存储生产者的消息
  5. RoutingKey(路由键)

image.png

RabbitMQ 有几种广播类型?

  1. fanout(扇出):所有 bind 到此 exchange 的 queue 都可以接收消息;
  2. direct(直连):通过 routingKey 和 exchange 中的 bindingKey 决定的那个唯一的 queue 可以接收消息;
  3. topic(主体):所有符合 routingKey 所 bind 的 queue 可以接收消息。

Kafka 可以脱离 zookeeper 单独使用吗?为什么?

Kafka 不能脱离 zookeeper 单独使用,因为 Kafka 使用 zookeeper 管理和协调 Kafka 的节点服务器。

补充:最新版本的 Kafka 2.8.0 版本实现了 Raft 分布式一致性机制,意味着可以脱离 ZooKeeper 独立运行

Kafka 有几种数据保留的策略?

1、按照过期时间保留(到时见就删除)

2、按照存储的消息大小保留(占用指定大小的磁盘后删除老消息)

Kafka 的分区策略有哪些?

谈下你对 Zookeeper 的认识?

Zookeeper 都有哪些功能?

谈下你对 ZAB 协议的了解?

Zookeeper 怎么保证主从节点的状态同步?

Zookeeper 有几种部署模式?

说一下 Zookeeper 的通知机制?

集群中为什么要有主节点?

集群中有 3 台服务器,其中一个节点宕机,这个时候 Zookeeper 还可以使用吗?

说一下两阶段提交和三阶段提交的过程?分别有什么问题?

Zookeeper 宕机如何处理?

说下四种类型的数据节点 Znode?

Zookeeper 和 Dubbo 的关系?

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

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

相关文章

排序——希尔排序、插入排序

本节复习排序中的希尔排序&#xff0c;希尔排序属于插入排序。 希尔排序的代码和插入排序非常类似。 思想却相对于插入排序来说复杂。 在复习希尔排序之前&#xff0c; 我们需要先复习一下插入排序。 目录 插入排序 插入过程 代码实现 希尔排序 希尔排序的思想 代码实…

蓝桥杯之【01背包模版】牛客例题展示

牛客链接 #include <bits/stdc.h> using namespace std; int n,V; const int N1010; int v[N],w[N]; int dp[N][N]; int main() {cin>>n>>V;for(int i1;i<n;i){cin>>v[i]>>w[i];}for(int i1;i<n;i){for(int j1;j<V;j){dp[i][j]dp[i-1][…

Svg Flow Editor 原生svg流程图编辑器(一)

系列文章 Svg Flow Editor 原生svg流程图编辑器&#xff08;二&#xff09; 效果展示 项目概述 svg flow editor 是一款流程图编辑器&#xff0c;提供了一系列流程图交互、编辑所必需的功能&#xff0c;支持前端研发自定义开发各种逻辑编排场景&#xff0c;如流程图、ER 图、…

【xv6操作系统】Lab systems calls

一、实验前须知 阅读 xv6 文档的第 2 章和第 4 章的 4.3 节和 4.4 节以及相关源文件&#xff1a; 系统调用的用户空间代码在 user/user.h 和 user/usys.pl 中。 内核空间代码在 kernel/syscall.h 和 kernel/syscall.c 中。 与进程相关的代码在 kernel/proc.h 和 kernel/proc.c…

CorelDRAW Standard2024适合业余爱好者和家庭企业的图形设计软件

CorelDRAW Standard 2024是一款功能强大的矢量图形设计软件&#xff0c;专为图形爱好者、家庭用户、微型企业和学生们设计。该软件在Windows平台上运行&#xff0c;并提供了智能对象、布局、插图和模板等功能&#xff0c;帮助用户快速创建高质量的设计作品。 CorelDRAW Standa…

图机器学习(4)-面向连接层面的人工特征工程

0 问题定义 通过已经连接去猜未知连接&#xff1a; 有两个思路&#xff1a; &#xff08;1&#xff09;直接提取link的特征&#xff0c;把link变成D维向量&#xff1b; &#xff08;2&#xff09;把link两端节点的D维向量拼在一起&#xff0c;缺点&#xff1a;丢失了link本身…

【C++】手撕string类(超实用!)

前言 一、标准库中的string类 1.1 string类介绍 1.2 string的常用接口 1.2.1 常用的构造函数 1.2.2 容量操作接口 &#xff08;1&#xff09;size &#xff08;2&#xff09;capacity &#xff08;3&#xff09;empty &#xff08;4&#xff09;clear &#xff08…

MySQL 学习笔记(基础篇 Day3)

「写在前面」 本文为黑马程序员 MySQL 教程的学习笔记。本着自己学习、分享他人的态度&#xff0c;分享学习笔记&#xff0c;希望能对大家有所帮助。推荐先按顺序阅读往期内容&#xff1a; 1. MySQL 学习笔记&#xff08;基础篇 Day1&#xff09; 2. MySQL 学习笔记&#xff08…

移掉 K 位数字(LeetCode 402)

文章目录 1.问题描述2.难度等级3.热门指数4.解题思路4.1 暴力法4.2 贪心 单调栈 参考文献 1.问题描述 给你一个以字符串表示的非负整数 num 和一个整数 k&#xff0c;移除这个数中的 k 位数字&#xff0c;使得剩下的整数最小。请你以字符串形式返回这个最小的整数。 示例 1 …

chrome插件开发的几种展现页面形式,3分钟看完

想要开发一个chrome浏览器插件&#xff0c;还是很有必要清楚插件都可以在哪些地方显示出来的&#xff0c;比如只想在pop页面弹出&#xff0c;还是添加右键菜单&#xff0c;还是提示桌面通知&#xff1f;还是在哪里展示&#xff1f;有哪些展示方式等 browserAction(浏览器右上角…

原油数据处理:1.聚类、盐含量测定与近红外光谱快速评估

一、原油种类的聚类分析 在塔里木盆地塔河油田的原油处理过程中&#xff0c;需要对原油进行地球化学特征研究&#xff0c;以了解其成因和特征。根据地球化学手段的综合研究结果&#xff0c;塔河油田奥陶系原油属于海相沉积环境&#xff0c;成熟度较高&#xff0c;正构烷烃分布…

内存映射实现父子进程通信

创建内存映射区&#xff1a; void *mmap(void *addr ,size_t length,int prot,int flags,int fd,off_t offset); 参数&#xff1a; addr 指定映射区的首地址。通常NULL&#xff0c;表示让系统自动分配length 共享内存映射区的长度prot 共享内存的读写属性 PROT_READ PR…

【记录37】VueBaiduMap 踩坑一

截图 错误 Error in callback for watcher “position.lng”: “TypeError: Cannot read properties of undefined (reading ‘setPosition’)” 解释 回调观察程序“content”时出错&#xff1a;“TypeError:无法读取未定义的属性&#xff08;读取’setContent’&#xff09;”…

数据结构:Heap(二叉树)的基本操作

目录 1.有关二叉树必须知道的几个基本概念 2.有关二叉树的基本操作 2.0有关元素的定义以及要进行的操作 2.1初始化和销毁操作 2.2插入操作以及上调操作 2.2.1插入操作以及上调操作的图解 2.2.2插入操作以及上调操作的代码 2.3删除根元素及其下调操作 2.3.2删除根元素及…

Android studio Gradle下载失败,如何手动配置解决该问题详解

前些天发现了一个蛮有意思的人工智能学习网站,8个字形容一下"通俗易懂&#xff0c;风趣幽默"&#xff0c;感觉非常有意思,忍不住分享一下给大家。 &#x1f449;点击跳转到教程 前言&#xff1a; 今天在打开公司一个项目时&#xff0c;突然要重新下载相关的gradle&am…

Websocket实时音视频传输应用实战

背 景 随着互联网技术的发展&#xff0c;越来越多的企业和开发者开始寻求更高效、更稳定的通信解决方案。在这种背景下&#xff0c;WebSocket协议应运而生。WebSocket是一种在单个TCP连接上进行全双工通信的协议&#xff0c;它可以实现服务器和客户端之间的实时数据交换&#…

图像处理 mask掩膜

1&#xff0c;图像算术运算 图像的算术运算有很多种&#xff0c;比如两幅图像可以相加&#xff0c;相减&#xff0c;相乘&#xff0c;相除&#xff0c;位运算&#xff0c;平方根&#xff0c;对数&#xff0c;绝对值等&#xff1b;图像也可以放大&#xff0c;缩小&#xff0c;旋…

(二十一)从零开始搭建k8s集群——kubernates核心组件及功能介绍

前言 Kubernetes是一个可移植、可扩展、开源的平台&#xff0c;用于管理容器化的工作负载和服务&#xff0c;它促进了声明性配置和自动化。Kubernetes容器可以持续开发、集成和部署&#xff1a;可靠且频繁地构建和部署容器镜像&#xff0c;快速有效地回滚&#xff1b;开发与运…

点胶缺陷视觉检测都是怎么检测的?

点胶工艺是许多工业生产中不可或缺的一环&#xff0c;而点胶缺陷的存在往往直接影响到产品质量。为了提升点胶工艺的品质控制&#xff0c;点胶缺陷的视觉检测成为了一个重要的技术手段。 一、点胶缺陷的类型 点胶缺陷主要包括胶点大小不均、位置偏移、漏点、多点等。这些缺陷如…

IntelliJ IDEA 2020.2.4试用方法

打开idea&#xff0c;准备好ide-eval-resetter压缩包。 将准备好的压缩包拖入idea中 选中弹窗中的自动重置选项&#xff0c;并点击重置 查看免费试用时长