消息中间件篇之Kafka-消息不丢失

一、 正常工作流程

生产者发送消息到kafka集群,然后由集群发送到消费者。

但是可能中途会出现消息的丢失。下面是解决方案。

二、 生产者发送消息到Brocker丢失

1. 设置异步发送

java 复制代码
    //同步发送
    RecordMetadata recordMetadata = kafkaProducer.send(record).get();
    //异步发送
    kafkaProducer.send(record,new Callback() {
        @Override public void onCompletion (RecordMetadata recordMetadata, Exception e){
            if (e != null) {
                System.out.println("消息发送失败 | 记录日志");
            }
            long offset = recordMetadata.offset();
            int partition = recordMetadata.partition();
            String topic = recordMetadata.topic();
        }
    });

2.消息重试

java 复制代码
//设置重试次数
prop.put(ProducerConfig.RETRIES_CONFIG,10);

三、消息在Brocker中存储丢失

发送确认机制acks。消息首先Topic是key,到达Topic以后才选择分区Partition(默认就一个分区,0号分区),默认连接的就是分区的Leader节点,由leader分区同步到follower区中。

四、消费者从Brocker接收消息丢失

1.分区机制

  1. Kafka 中的分区机制指的是将每个主题划分成多个分区(Partition)。

  2. topic分区中消息只能由消费者组中的唯一一个消费者 处理,不同的分区分配给不同的消费者(同一个消费者组)。

2.消费方式

消费者默认是自动按期提交已经消费的偏移量 ,默认是每隔5s提交一次,如果出现重平衡的情况,可能会重复消费或丢失数据

3.那如何解决重复消费

禁用自动提交偏移量,改为手动: 1. 同步提交。 2. 异步提交。 3. 同步+异步组合提交。

五、面试题

面试官:Kafka是如何保证消息不丢失?

候选人:嗯,这个保证机制很多,在发送消息到消费者接收消息,在每个阶段都有可能会丢失消息,所以我们解决的话也是从多个方面考虑:

第一个是生产者发送消息的时候,可以使用异步回调发送,如果消息发送失败,我们可以通过回调获取失败后的消息信息,可以考虑重试或记录日志,后边再做补偿都是可以的。同时在生产者这边还可以设置消息重试,有的时候是由于网络抖动的原因导致发送不成功,就可以使用重试机制来解决。

第二个在broker中消息有可能会丢失,我们可以通过kafka的复制机制来确保消息不丢失,在生产者发送消息的时候,可以设置一个acks,就是确认机制。我们可以设置参数为all,这样的话,当生产者发送消息到了分区之后,不仅仅只在leader分区保存确认,在follwer分区也会保存确认,只有当所有的副本都保存确认以后才算是成功发送了消息,所以,这样设置就很大程度了保证了消息不会在broker丢失。

第三个有可能是在消费者端丢失消息,kafka消费消息都是按照offset进行标记消费的,消费者默认是自动按期提交已经消费的偏移量,默认是每隔5s提交一次,如果出现重平衡的情况,可能会重复消费或丢失数据。我们一般都会禁用掉自动提价偏移量,改为手动提交,当消费成功以后再报告给broker消费的位置,这样就可以避免消息丢失和重复消费了。

面试官:Kafka中消息的重复消费问题如何解决的?

候选人:kafka消费消息都是按照offset进行标记消费的,消费者默认是自动按期提交已经消费的偏移量,默认是每隔5s提交一次,如果出现重平衡的情况,可能会重复消费或丢失数据。我们一般都会禁用掉自动提价偏移量,改为手动提交,当消费成功以后再报告给broker消费的位置,这样就可以避免消息丢失和重复消费了。

为了消息的幂等,我们也可以设置唯一主键来进行区分,或者是加锁,数据库的锁,或者是redis分布式锁,都能解决幂等的问题。

相关推荐
Allen Bright15 分钟前
Java代码操作Zookeeper(使用 Apache Curator 库)
java·zookeeper·java-zookeeper
云上星空23 分钟前
K8s调度器扩展(scheduler)
java·贪心算法·kubernetes
突然好想你之路在脚下31 分钟前
Kubernetes(k8s)入门到实战教程
java·容器·kubernetes
博观而约取35 分钟前
Jenkins升级到最新版本后无法启动
java·linux·centos·jenkins
yang_shengy1 小时前
【JavaEE】多线程(2)
java·开发语言·多线程·
lix的小鱼1 小时前
scala之全文单词统计
java·开发语言·后端·python·算法·c#·scala
GGBondlctrl1 小时前
【Spring MVC】关于Spring MVC编程中前后端交互实现简单登录跳转和留言板实例
java·spring mvc·lombok·前后端交互·登录跳转·留言板·接口文档定义
小白不太白9501 小时前
设计模式之 访问者模式
java·设计模式·访问者模式
怀旧6661 小时前
Java LinkedList 讲解
java·开发语言·后端·个人开发
冷心笑看丽美人1 小时前
setter方法注入(Java EE 学习笔记07)
java·笔记·学习·spring·java-ee·javaee