我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第一篇文章,点击查看活动详情
问题现象
有一个消息量不大的topic,偶尔会报json格式非法的错误。最开始以为是脏数据没有处理,最后在空闲的时候去仔细的研究了下报错的原因。
@KafkaListener(topics = "test", groupId = "test-group")
public void listen(String message) {
if (StringUtils.isEmpty(message)) {
log.info("receive empty, return");
return;
}
log.info("收到的热度信息为:{}", message);
try {
if (!StringUtils.isEmpty(message)) {
doSomething(message)
}
} catch (Exception ex) {
log.info("update error for {}", message);
}
}
代码很简单,乍一看没什么问题,但是实际上检查kafka中消费格式正确,所以问题一定出在消费配置上。这个listener注解下方法的入参形式多样,注解如何适配不同参数也引起我的好奇。
原理分析
Spring中@KafkaListener注解原理:
@KafkaListener工作流程主要有以下几步:
- 解析:解析@KafkaListener注解。
- 注册:解析后的数据注册到spring-kafka。
- 监听:开始监听topic变更。
- 调用:调用注解标识的方法,将监听到的数据作为参数传入。
第四步方法入口:invokeListener
批消费模式下进入批消费的监听方法。
注册回调
具体的反射方法
此时可以看到list已经被转换为string
继续追踪转换方法
类型转换器:
类型转换器:
集合到String类型转换器
list转String关键代码,list添加,append(",")的方式转换为集合
解决方法
- 方式一:入参修改为list即可,集合转集合就不会出现kafka自定义的转换
- 方式二:修改批模式为流模式(底层永远是批拉)