前言

本文主要讲述一下spring for kafka的consumer在spring.kafka.consumer.enable-auto-commit是false情况下,AckMode的选项,及手动提交分析总结。

AckMode

RECORD
每处理一条commit一次
BATCH(默认)
每次poll的时候批量提交一次,频率取决于每次poll的调用频率
TIME
每次间隔ackTime的时间去commit(跟auto commit interval有什么区别呢?)
COUNT
累积达到ackCount次的ack去commit
COUNT_TIME
ackTime或ackCount哪个条件先满足,就commit
MANUAL
listener负责ack,但是背后也是批量上去
MANUAL_IMMEDIATE
listner负责ack,每调用一次,就立即commit

Manual Commit

  • 消费端手动提交offset代码如下:
  /**
* 这是手动提交的消费方式
* @param record
* @param ack
* @throws Exception
*/
@KafkaListener(topics = TopicConstants.COMMON_PAY,groupId = "写自己的消费组 id")
public void listenXXXPay(ConsumerRecord<String, String> record , Acknowledgment ack) throws Exception {
String msg = JSONObject.parseObject(record.value(), String.class);
System.out.println(msg);
if (new Random().nextInt(100)<50){
logger.info(String.format("kafka 综合收费消费消息成功---------------- listen1 topic = %s, offset = %d, value = %s ", record.topic(), record.offset(), record.value()));
ack.acknowledge();
}
}

前提要配置AckMode:

instance.getContainerProperties().setAckMode(AbstractMessageListenerContainer.AckMode.MANUAL);
  • 接下来问题来了, 如果代码中没有进行ack.acknowledge(),会怎么办呢??

消费者在消费消息的过程中,配置参数设置为不自动提交offset,在消费完数据之后如果不手动提交offset,那么在程序中和kafak中的数据会如何被处理呢?

1. 如果在消费kafka的数据过程中,一直没有提交offset,那么在此程序运行的过程中它不会重复消费。但是如果重启之后,就会重复消费之前没有提交offset的数据。

2. 如果在消费的过程中有几条或者一批数据数据没有提交offset,后面其他的消息消费后正常提交offset,那么服务端会更新为消费后最新的offset,不会重新消费,就算重启程序也不会重新消费。

3. 消费者如果没有提交offset,程序不会阻塞或者重复消费,除非在消费到这个你不想提交offset的消息时你尝试重新初始化一个客户端消费者,即可再次消费这个未提交offset的数据。因为客户端也记录了当前消费者的offset信息,所以程序会在每次消费了数据之后,自己记录offset,而手动提交到服务端的offset与这个并没有关系,所以程序会继续往下消费。在你重新初始化客户端消费者之后,会从服务端得到最新的offset信息记录到本地。所以说如果当前的消费的消息没有提交offset,此时在你重新初始化消费者之后,可得到这条未提交消息的offset,从此位置开始消费。

Spring-Kafka —— 消费后不提交offset情况的分析总结的更多相关文章

  1. Spring-Kafka —— 实现批量消费和手动提交offset

    spring-kafka的官方文档介绍,可以知道自1.1版本之后, @KafkaListener开始支持批量消费,只需要设置batchListener参数为true 把application.yml中 ...

  2. Kafka提交offset机制

    在kafka的消费者中,有一个非常关键的机制,那就是offset机制.它使得Kafka在消费的过程中即使挂了或者引发再均衡问题重新分配Partation,当下次重新恢复消费时仍然可以知道从哪里开始消费 ...

  3. Kafka在高并发的情况下,如何避免消息丢失和消息重复?kafka消费怎么保证数据消费一次?数据的一致性和统一性?数据的完整性?

    1.kafka在高并发的情况下,如何避免消息丢失和消息重复? 消息丢失解决方案: 首先对kafka进行限速, 其次启用重试机制,重试间隔时间设置长一些,最后Kafka设置acks=all,即需要相应的 ...

  4. Kafka消费不到数据的特殊情况

    我大约是把kafka消费不到数据的特殊情况都经历了一遍了吧= =. kafka消费不到数据的原因,首先检查配置之类的,如是否设置了group.id,对应的topic是否正确等等,这些不多说. 下面是我 ...

  5. kafka消费端提交offset的方式

    Kafka 提供了 3 种提交 offset 的方式 自动提交 复制 1234 consumer.commitSync(); 手动异步提交 offset 复制 1 consumer.commitAsy ...

  6. Spring Kafka和Spring Boot整合实现消息发送与消费简单案例

    本文主要分享下Spring Boot和Spring Kafka如何配置整合,实现发送和接收来自Spring Kafka的消息. 先前我已经分享了Kafka的基本介绍与集群环境搭建方法.关于Kafka的 ...

  7. Kafka技术内幕 读书笔记之(三) 消费者:高级API和低级API——消费者消费消息和提交分区偏移量

    消费者拉取钱程拉取每个分区的数据,会将分区的消息集包装成一个数据块( FetchedDataChunk )放入分区信息的队列中 . 而每个队列都对应一个消息流( KafkaStream ),消费者客户 ...

  8. 【Kafka】《Kafka权威指南》——提交和偏移量

    KafkaConsumer(消费者)每次调用 poll()方法,它总是返回由生产者写入 Kafka但还没有被消费者读取过的记录, 我们因 此可以追踪到哪些记录是被群组里的哪个消费者读取的.之前已经讨论 ...

  9. kafka消费组、消费者

    consumer group consumer instance 一个消费组可能有一个或者多个消费者.同一个消费组可以订阅一个或者多个主题.主题的某一个分区只能被消费组的某一个消费者消费.那么分区和消 ...

随机推荐

  1. 前端自动化构建工具 Webpack——3 webpack配置文件的使用

  2. pandas df 遍历行方法

    pandas 遍历有以下三种访法. iterrows():在单独的变量中返回索引和行项目,但显着较慢 itertuples():快于.iterrows(),但将索引与行项目一起返回,ir [0]是索引 ...

  3. macOS上更顺手的终端

    安装iTerm2.下载地址 https://iterm2.com/downloads/stable/latest 安装Nerd Fonts.下载地址 https://github.com/ryanoa ...

  4. 题解 [CF891C] Envy

    题面 解析 首先根据Kruskal算法, 我们可以知道, 在加入权值为\(w\)的边时, 权值小于\(w\)的边都已经加进树里了(除了连成环的). 所以,我们可以保存一下每条边的端点在加入生成树之前的 ...

  5. encodeURI()、encodeURIComponent()、escape()

    URI的通用格式如下: /*** 协议://用户名:密码@子域名.域名.顶级域名:端口号/目录/文件名.文件后缀?参数1=值1&参数2=值2+值3#标志 **/ /*** http://use ...

  6. 小米oj 帮小学生排队(排序+插入)

     帮小学生排队 序号:#18难度:有挑战时间限制:1000ms内存限制:10M 描述 用一个数组表示一群正在排队的小学生,每个小学生用一对整数 H, K 来表示:H 表示这个小学生的身高,K 表示这个 ...

  7. 「BZOJ 4565」「HAOI 2016」字符合并「区间状压DP」

    题意 给一个长度为\(n(\leq 300)\)的\(01\)串,每次可以把\(k(\leq 8)\)个相邻字符合并,得到新字符和一定分数,最大化最后的得分 题解 考虑设计dp:\(dp[S][i][ ...

  8. Flask-特殊的装饰器

    视图函数中的装饰器 -----------------------视图中的装饰器---------------------- 1.如果使用的是函数视图,那么自己定义的装饰器必须放在`app.route ...

  9. javaScript基础用Number()把其它类型转换为Number类型

    一:基本类型 字符串 把字符串转换为数字,只要字符串中包含任意一个非有效数字字符(第一个点除外)结果都是NaN,空字符串会变为数字零 console.log(Number("12.5&quo ...

  10. LGU67496 小$s$的玻璃弹珠

    题意 在一幢\(m\)层建筑你将获得\(n\)个一样的鸡蛋,从高于\(x\)的楼层落下的鸡蛋都会碎.如果一个蛋碎了,你就不能再把它掉下去. 你的目标是确切地知道\(x\)的值.问至少要扔几次才能确定. ...