您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

面试官竟然问我消息队列为啥会丢失消息?幸亏我总结了全套八股文

时间:2022-04-27 09:27:16  来源:  作者:一灯架构

一个挺着啤酒肚,身穿格子衫,发际线严重后移的中年男子,手拿着保温杯,胳膊夹着macBook向你走来,看样子是架构师级别。

面试开始,直入正题。

面试官: 我看到你的简历上写着项目中用到了消息队列,还用的是kafka,你有遇到过消息队列丢失消息的情况吗?

我: 消息队列还能丢失消息?那谁还用消息队列!你是不是搞错了?我没遇到过丢失消息的情况,也没考虑过这个问题。

面试官: 嗯...,小伙子,看来有些面试套路,你还是不太懂。今天面试就先到这里吧!给你的简历,我送你下楼。

我去!面试还有啥套路?
能不能少一点套路,多一点真诚!
难道都要去背一遍八股文才能参加面试?
好吧,我去瞅一眼一灯总结的面试八股文。

面试官竟然问我消息队列为啥会丢失消息?幸亏我总结了全套八股文

 

我: 消息队列发送消息和消费消息的过程,共分为三段,生产过程、服务端持久化过程、消费过程,如下图所示。

 

面试官竟然问我消息队列为啥会丢失消息?幸亏我总结了全套八股文

 

这三个过程都有可能弄丢消息。

面试官: 嗯,消息丢失的具体原因是什么?怎么防止丢失消息呢?

我: 我详细说一下这种情况:

一、生产过程丢失消息

丢失原因:一般可能是网络故障,导致消息没有发送出去。

解决方案:重发就行了。

由于kafka为了提高性能,采用了异步发送消息。我们只有获取到发送结果,才能确保消息发送成功。 有两个方案可以获取发送结果。

一种是kafka把发送结果封装在Future对象中,我可以使用Future的get方法同步阻塞获取结果。


Future<RecordMetadata> future = producer.send(new ProducerRecord<>(topic, message));
try {
    RecordMetadata recordMetadata = future.get();
    if (recordMetadata != null) {
        System.out.println("发送成功");
    }
} catch (Exception e) {
    e.printStackTrace();
}

另一种是使用kafka的callback函数获取返回结果。

producer.send(new ProducerRecord<>(topic, message), new Callback() {
    @Override
    public void onCompletion(RecordMetadata metadata, Exception exception) {
        if (exception == null) {
            System.out.println("发送成功");
        } else {
            System.out.println("发送失败");
        }
    }
});

如果发送失败了,有两种重试方案:

  1. 手动重试 在catch逻辑或else逻辑中,再调用一次send方法。如果还不成功怎么办? 在数据库中建一张异常消息表,把失败消息存入表中,然后搞个异步任务重试,便于控制重试次数和间隔时间。
  2. 自动重试 kafka支持自动重试,设置参数如下,当集群Leader选举中或者Follower数量不足等原因返回失败时,就可以自动重试。
  3. # 设置重试次数为3
    retries = 3# 设置重试间隔为100msretry.backoff.ms = 100
  4. 一般我们不会用kafka自动重试,因为超过重试次数,还是会返回失败,还需要我们手动重试。

二、服务端持久化过程丢失消息

为了保证性能,kafka采用的是异步刷盘,当我们发送消息成功后,Broker节点在刷盘之前宕机了,就会导致消息丢失。

当然我们也可以设置刷盘频率:

# 设置每1000条消息刷一次盘
flush.messages = 1000
# 设置每秒刷一次盘
flush.ms = 1000

先普及一下kafka集群的架构模型:

kafka集群由多个broker组成,一个broker就是一个节点(机器)。 一个topic有多个partition(分区),每个partition分布在不同的broker上面,可以充分利用分布式机器性能,扩容时只需要加机器、加partition就行了。

 

面试官竟然问我消息队列为啥会丢失消息?幸亏我总结了全套八股文

 

 

一个partition又有多个replica(副本),有一个leader replica(主副本)和多个follower replica(从副本),这样设计是为了保证数据的安全性。

发送消息和消费消息都在leader上面,follower负责定时从leader上面拉取消息,只有follower从leader上面把这条消息拉取回来,才算生产者发送消息成功。

kafka为了加快持久化消息的性能,把性能较好的follower组成一个ISR列表(in-sync replica),把性能较差的follower组成一个OSR列表(out-of-sync replica),ISR+OSR=AR(assigned repllicas)。 如果某个follower一段时间没有向leader拉取消息,落后leader太多,就把它移出ISR,放到OSR之中。 如果某个follower追上了leader,又会把它重新放到ISR之中。 如果leader挂掉,就会从ISR之中选一个follower做leader。

 

面试官竟然问我消息队列为啥会丢失消息?幸亏我总结了全套八股文

 

 

为了提升持久化消息性能,我们可以进行一些设置:

# 如果follower超过一秒没有向leader拉取消息,就把它移出ISR列表
rerplica.lag.time.max.ms = 1000
# 如果follower落后leader一千条消息,就把它移出ISR列表
rerplica.lag.max.messages = 1000

# 至少保证ISR中有3个follower
min.insync.replicas = 3

# 异步消息,不需要leader确认,立即给生产者返回发送成功,丢失消息概率较大
asks = 0
# leader把消息写入本地日志中,不会等所有follower确认,就给生产者返回发送成功,小概率丢失消息
asks = 1
# leader需要所有ISR中follower确认,才给生产者返回发送成功,不会丢失消息
asks = -1 或者 asks = all

三、消费过程丢失消息

kafka中有个offset的概念,consumer从partition中拉取消息,consumer本地处理完成后需要commit一下offset,表示消费完成,下次就不会再拉取到这条消息。
所以我们需要关闭自动commit offset的配置,防止consumer拉到消息后,服务宕机,导致消息丢失。

enable.auto.commit = false

面试官: 还得是你,就你总结的全,我都想不那么全,明天来上班吧,薪资double。

 

本文知识点总结:

 

面试官竟然问我消息队列为啥会丢失消息?幸亏我总结了全套八股文

 



Tags:消息队列   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
如何使用 Redis 实现消息队列
Redis不仅是一个强大的内存数据存储系统,它还可以用作一个高效的消息队列。消息队列是应用程序间或应用程序内部进行异步通信的一种方式,它允许数据生产者将消息放入队列中,然...【详细内容】
2024-03-22  Search: 消息队列  点击:(22)  评论:(0)  加入收藏
消息队列备选架构选择,你选择哪个?
中间件团队的研发人员认为这个方案比较简单,实现成本低,但测试代表认为这个方案测试人力投入较大。运维团队认为这个方案的硬件成本比较高,一个数据分组就需要4台机器(2台服务器...【详细内容】
2023-11-30  Search: 消息队列  点击:(186)  评论:(0)  加入收藏
四种消息队列,如何选型?
最近发现很多号主发消息队列的文章,质量参差不齐,相关文章我之前也写过,建议直接看这篇。这篇文章,主要讲述 Kafka、RabbitMQ、RocketMQ 和 ActiveMQ 这 4 种消息队列的异同,无论...【详细内容】
2023-11-27  Search: 消息队列  点击:(196)  评论:(0)  加入收藏
几款主流消息队列之间的差异,我们应该如何选择
为什么需要消息队列消息队列是历史最悠久的中间件之一,它可以和不同的进程进行通信,从而实现上下游之间的消息传递。基于此特性,我们可以在以下三个场景中使用消息队列。 解耦; ...【详细内容】
2023-11-17  Search: 消息队列  点击:(128)  评论:(0)  加入收藏
常用消息队列框架与技术选型
又是一年双11季,土豪们买买买,程序员看看热闹,聊聊技术。海量的订单、支付请求以及库存更新等任务,离不开分布式架构(SOFAStack)、分布式数据库(OceanBase)、分布式缓存(Tair)、数据处...【详细内容】
2023-11-13  Search: 消息队列  点击:(207)  评论:(0)  加入收藏
Java中的消息队列实战,构建高效异步系统
随着互联网应用的发展,高效的异步系统变得越来越重要。在这样的系统中,消息队列起到了关键的作用。通过消息队列,可以将不同组件之间的耦合度降低,实现解耦和异步处理,提高系统的...【详细内容】
2023-11-07  Search: 消息队列  点击:(325)  评论:(0)  加入收藏
热门的消息队列框架比较、使用方法、优缺点,提供示例代码
消息队列(Message Queue)是一种在分布式系统中用于消息传递的通信模式。它可以将消息发送者和接收者解耦,提高系统的可靠性、可扩展性和可维护性。下面将详细介绍3-5个常用的...【详细内容】
2023-10-11  Search: 消息队列  点击:(156)  评论:(0)  加入收藏
为什么我们需要消息队列?
消息队列有着悠久的历史,它们经常用于不同系统之间的通信。图1通过将其与星巴克的工作方式进行比较,阐述了消息队列的概念。在星巴克,收银员接受订单并收取款项,然后在咖啡杯上...【详细内容】
2023-09-05  Search: 消息队列  点击:(353)  评论:(0)  加入收藏
使用 SQL 的方式查询消息队列数据以及踩坑指南
Pulsar-SQL 是一个非常有用的功能,只是我们使用过程中确实发现了一些问题,大部分都已经修复了;希望对后续使用该功能的朋友有所帮助。背景为了让业务团队可以更好的跟踪自己消...【详细内容】
2023-08-31  Search: 消息队列  点击:(276)  评论:(0)  加入收藏
Java消息队列开发实战,打造高效异步处理
随着互联网应用的发展,高效的异步系统变得越来越重要。在这样的系统中,消息队列起到了关键的作用。通过消息队列,可以将不同组件之间的耦合度降低,实现解耦和异步处理,提高系统的...【详细内容】
2023-08-30  Search: 消息队列  点击:(358)  评论:(0)  加入收藏
▌简易百科推荐
Meta如何将缓存一致性提高到99.99999999%
介绍缓存是一种强大的技术,广泛应用于计算机系统的各个方面,从硬件缓存到操作系统、网络浏览器,尤其是后端开发。对于Meta这样的公司来说,缓存尤为重要,因为它有助于减少延迟、扩...【详细内容】
2024-04-15    dbaplus社群  Tags:Meta   点击:(1)  评论:(0)  加入收藏
SELECT COUNT(*) 会造成全表扫描?回去等通知吧
前言SELECT COUNT(*)会不会导致全表扫描引起慢查询呢?SELECT COUNT(*) FROM SomeTable网上有一种说法,针对无 where_clause 的 COUNT(*),MySQL 是有优化的,优化器会选择成本最小...【详细内容】
2024-04-11  dbaplus社群    Tags:SELECT   点击:(1)  评论:(0)  加入收藏
10年架构师感悟:从问题出发,而非技术
这些感悟并非来自于具体的技术实现,而是关于我在架构设计和实施过程中所体会到的一些软性经验和领悟。我希望通过这些分享,能够激发大家对于架构设计和技术实践的思考,帮助大家...【详细内容】
2024-04-11  dbaplus社群    Tags:架构师   点击:(2)  评论:(0)  加入收藏
Netflix 是如何管理 2.38 亿会员的
作者 | Surabhi Diwan译者 | 明知山策划 | TinaNetflix 高级软件工程师 Surabhi Diwan 在 2023 年旧金山 QCon 大会上发表了题为管理 Netflix 的 2.38 亿会员 的演讲。她在...【详细内容】
2024-04-08    InfoQ  Tags:Netflix   点击:(5)  评论:(0)  加入收藏
即将过时的 5 种软件开发技能!
作者 | Eran Yahav编译 | 言征出品 | 51CTO技术栈(微信号:blog51cto) 时至今日,AI编码工具已经进化到足够强大了吗?这未必好回答,但从2023 年 Stack Overflow 上的调查数据来看,44%...【详细内容】
2024-04-03    51CTO  Tags:软件开发   点击:(9)  评论:(0)  加入收藏
跳转链接代码怎么写?
在网页开发中,跳转链接是一项常见的功能。然而,对于非技术人员来说,编写跳转链接代码可能会显得有些困难。不用担心!我们可以借助外链平台来简化操作,即使没有编程经验,也能轻松实...【详细内容】
2024-03-27  蓝色天纪    Tags:跳转链接   点击:(16)  评论:(0)  加入收藏
中台亡了,问题到底出在哪里?
曾几何时,中台一度被当做“变革灵药”,嫁接在“前台作战单元”和“后台资源部门”之间,实现企业各业务线的“打通”和全域业务能力集成,提高开发和服务效率。但在中台如火如荼之...【详细内容】
2024-03-27  dbaplus社群    Tags:中台   点击:(13)  评论:(0)  加入收藏
员工写了个比删库更可怕的Bug!
想必大家都听说过删库跑路吧,我之前一直把它当一个段子来看。可万万没想到,就在昨天,我们公司的某位员工,竟然写了一个比删库更可怕的 Bug!给大家分享一下(不是公开处刑),希望朋友们...【详细内容】
2024-03-26  dbaplus社群    Tags:Bug   点击:(9)  评论:(0)  加入收藏
我们一起聊聊什么是正向代理和反向代理
从字面意思上看,代理就是代替处理的意思,一个对象有能力代替另一个对象处理某一件事。代理,这个词在我们的日常生活中也不陌生,比如在购物、旅游等场景中,我们经常会委托别人代替...【详细内容】
2024-03-26  萤火架构  微信公众号  Tags:正向代理   点击:(14)  评论:(0)  加入收藏
看一遍就理解:IO模型详解
前言大家好,我是程序员田螺。今天我们一起来学习IO模型。在本文开始前呢,先问问大家几个问题哈~什么是IO呢?什么是阻塞非阻塞IO?什么是同步异步IO?什么是IO多路复用?select/epoll...【详细内容】
2024-03-26  捡田螺的小男孩  微信公众号  Tags:IO模型   点击:(10)  评论:(0)  加入收藏
站内最新
站内热门
站内头条