一 参数分析
这里就涉及到的问题是,消费者在创建时会有一个属性max.poll.interval.ms,该属性意思为kafka消费者在每一轮poll()调用之间的最大延迟,消费者在获取更多记录之前可以空闲的时间量的上限。如果此超时时间期满之前poll()没有被再次调用,则消费者被视为失败,并且分组将重新平衡,以便将分区重新分配给别的成员。
循环调用poll拉取broker中的最新消息。每次拉取后,会有一段处理时长,处理完成后,会进行下一轮poll。引入该配置的用途是,限制两次poll之间的间隔,消息处理逻辑太重,每一条消息处理时间较长,
但是在这次poll()到下一轮poll()时间不能超过该配置间隔,协调器会明确地让使用者离开组,并触发新一轮的再平衡。
二 问题分析与解决
首先,设置了自动提交。
尽管这不是生产建议配置,但我们还是这么做了。项目运行半年多,没出现什么问题。直到这次业务逻辑更改…
“enable.auto.commit”, true
有这两个参数,与业务处理紧密相关,更改业务逻辑之前,这两个参数分别是
max.poll.records:1000
“max.poll.interval.ms”,300000
300秒处理1000条数据插入,数据已存在直接跳过。
近期,项目业务逻辑更改,先用id查数据库,如果数据已存在,更新。如果不存在,插入。
更改业务逻辑后,消费者出现重复消费情况。经过排查,发现业务更逻辑改后,原来设置的参数不能满足消费者需求。
随后出现重复消费问题。加上时间戳,发现是业务处理时间过长。300秒处理不完业务逻辑(由于业务逻辑复杂,业务处理10条消息,耗时在30s到150s)
随后更改max.poll.records:20,重复消费偶尔出现,
随后更改max.poll.records:15,重复消费偶尔出现,
而后更改max.poll.records:10,重复消费不在出现。
更改参数后,kafka没有消息堆积,也不出现重复消费。参数更改告一段落。
三 总结
max.poll.interval.ms
主要涉及对此参数的理解,消费者两次poll()之间的最大时间间隔。所以一次poll()的处理时间要小于这个时间。
四 附上消费者参数配置
@Configuration
@EnableKafka
public class KafkaConsumerConfig {
@Value("${kafka.bootstrap-servers:ip1:9092,ip2:9092,ip3:9092}")
private String connectionPath;
@Value<