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 的关系?

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【数据结构】单链表的层层实现!! !

关注小庄 顿顿解馋(●’◡’●) 上篇回顾 我们上篇学习了本质为数组的数据结构—顺序表&#xff0c;顺序表支持下标随机访问而且高速缓存命中率高&#xff0c;然而可能造成空间的浪费&#xff0c;同时增加数据时多次移动会造成效率低下&#xff0c;那有什么解决之法呢&#xff…

Matlab|2机5节点牛拉法(含报告)

目录 主要内容 下载链接 主要内容 采用牛拉法计算2机5节点的潮流计算程序&#xff0c;程序迭代稳定&#xff0c;运行可靠&#xff0c;含报告资料。 下载链接

pytorch的梯度图与autograd.grad和二阶求导

前向与反向 这里我们从 一次计算 开始比如 zf(x,y) 讨论若我们把任意对于tensor的计算都看为函数&#xff08;如将 a*b&#xff08;数值&#xff09; 看为 mul(a,b)&#xff09;&#xff0c;那么都可以将其看为2个过程&#xff1a;forward-前向&#xff0c;backward-反向在pyto…

【Web】浅聊Java反序列化之C3P0——JNDI注入利用

目录 简介 原理分析 EXP 前文&#xff1a;【Web】浅聊Java反序列化之C3P0——URLClassLoader利用 【Web】浅聊Java反序列化之C3P0——不出网Hex字节码加载利用 简介 出网的情况下&#xff0c;这个C3P0的Gadget可以和fastjson&#xff0c;Snake YAML , JYAML,Yamlbeans , …

【Javascript编程实操05】1、小明买洗发水、香皂、牙刷组合 2、利用循环写出100以内的奇数的和及偶数的和

前言 1、小明买洗发水、香皂、牙刷组合 代码&#xff1a; 实现效果&#xff1a; 2、利用循环写出100以内的奇数的和及偶数的和 代码&#xff1a; 实现效果&#xff1a; 总结 前言 本次主要是继续针对Javascript阶段的for循环的实操练习&#xff0c;共有2个实操&#xff…

vscode setting.json 全局设置 工作区设置 位置 优先级

vscode中setting.json有两种配置权限 一、全局配置&#xff1a;setting.json文件位于C:\Users\Administrator\AppData\Roaming\Code\User\settings.json 二、工作区配置&#xff1a;setting.json文件位于工作区的.vscode\settings.json 当两种配置同时存在时&#xff0c;工作区…

单链表详解(如何实现单链表)

文章目录 前言 一、单链表是什么&#xff1f;二、单链表的实现总结 顺序表的缺点 1.中间/头部的插入删除&#xff0c;时间复杂度为O (N) 2.realloc 扩容&#xff08;特别是异地扩&#xff0c;需要申请新空间&#xff0c;拷贝数据&#xff0c;释放旧空间&#xff09;会有不小的…

【开源】JAVA+Vue.js实现高校宿舍调配管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能需求2.1 学生端2.2 宿管2.3 老师端 三、系统展示四、核心代码4.1 查询单条个人习惯4.2 查询我的室友4.3 查询宿舍4.4 查询指定性别全部宿舍4.5 初次分配宿舍 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的…

Day24:安全开发-PHP应用文件管理模块显示上传黑白名单类型过滤访问控制

目录 文件管理模块-上传-过滤机制 文件管理模块-显示-过滤机制 思维导图 PHP知识点 功能&#xff1a;新闻列表&#xff0c;会员中心&#xff0c;资源下载&#xff0c;留言版&#xff0c;后台模块&#xff0c;模版引用&#xff0c;框架开发等 技术&#xff1a;输入输出&#…

泛微OA服务器获取 token

泛微OA服务器获取 token 文章目录 泛微OA服务器获取 token一、泛微官方方法1 ecology 系统配置2 发放/生成许可证(appid)3 限制许可证使用ip地址&#xff08;该步骤也可以跳过&#xff09;4 使用 postman 注册5 获取 token6 访问业务系统接口 二、java 代码获取 token三、封装到…

【Redis项目实战】使用Springcloud整合Redis分布式锁+RabbitMQ技术实现高并发预约管理处理系统

&#x1f389;&#x1f389;欢迎光临&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;特别推荐给大家我的最新专栏《Redis实战与进阶》 本专栏带你Redis从入门到入魔 这是苏泽的个…

一次生产环境上的dockerd启动失败原因分析

今夜原计划对 生产环境 上的 SDN 组件进行一次紧急扩容操作的&#xff0c;但业务基础环境中的 Docker-Engine 启动不起来了、原定计划也就无法继续进行了。 尽管查清了基础业务环境中的故障原因&#xff0c;但金主DD说今天先不干了&#xff0c;那就整理整理思路写篇流水账吧 。…

Linux环境下使用线程方式操作UART读写功能

目录 概述 1 Linux环境下UART设备 2 轮询方式操作UART功能实现 2.1 打开串口函数&#xff1a;usr_serial_open 2.2 关闭串口函数&#xff1a; usr_serial_close 2.3 发送数据函数&#xff1a; usr_serial_sendbytes 2.4 接收数据函数&#xff1a; thread_uart_readbytes …

波卡 Alpha 计划启动,呼唤先锋创新者重新定义 Web3 开发

原文&#xff1a;https://polkadot.network/blog/the-polkadot-alpha-program-a-new-era-for-decentralized-building-collaboration/ 编译&#xff1a;OneBlock 区块链领域不断发展&#xff0c;随之而来的是发展和创新机会的增加。而最新里程碑是令人振奋的 Polkadot Alpha …

生态,带给用友新机会? | ToB产业观察

ITValue 近年来&#xff0c;不少厂商都将生态调整到战略级别&#xff0c;但做生态往往需要实打实、接地气的生态策略。 作者&#xff5c;杨丽 首发&#xff5c;钛媒体APP ITValue 3月初&#xff0c;用友召开了新一年的首场生态发布会&#xff0c;为接下来一年动作定调&#xff…

17、电源管理入门之Power supply子系统

目录 1. Power supply框架都做些什么 2. 相关数据结构和接口 2.1 数据结构 2.2 接口 3. 充电驱动 3.1 Charger Manager 3.2 Fuel Gauge 3.3 Charger IC 4. 怎样基于power supply class编写PSY driver 参考资料: 对于便携设备来说,电源管理更加的重要,因为电池电量…

数据库系统概念(第一周)

⚽前言 &#x1f3d0;四个基本概念 一、数据 定义 种类 特点 二、数据库 三、数据库管理系统&#xff08;DBMS&#xff09; 四、 数据库系统&#xff08;DBS&#xff09; &#x1f3c0;数据库系统和文件系统对比 文件系统的弊端 &#x1f94e;数据视图 数据抽象 …

jeecgboot 新建子模块 使用@EXCEL实现实现导入导出功能

一&#xff0c;用框架生成增删改查模块 二&#xff0c;在实体类entity 需要导入导出的字段上加上注解Excel 三&#xff0c;在controller类上继承jeecgboot通用controller JeecgController 并且在JeecgController里增加导出模板的方法 /*** 导出excel空模板** param req…

融资项目——网关微服务

1. 网关的路由转发功能 在前后端分离的项目中&#xff0c;网关服务可以将前端的相关请求转发到相应的后端微服务中。 2. 网关微服务的配置 首先需要创建一个网关微服务&#xff0c;并添加依赖。 <!-- 网关 --><dependency><groupId>org.springframework.cl…

相似矩阵及其对角化

目录 相似矩阵 矩阵的相似对角化 对称矩阵的相似对角化 相似矩阵 矩阵的相似对角化 对称矩阵的相似对角化