记录一个kafka发送消息后无法接收消息问题

本文记录了一个在Kafka中遇到的问题,即发送消息后无法接收。通过检查ConsumerOffsetChecker,发现存在堆积消息。问题在于设置的partition为0,导致同一组内只有一个consumer能消费。解决方法包括增加partition数量或修改consumer配置。此外,还提供了删除和创建topic,以及手动消费和生产消息的命令示例。

记录一个kafka发送消息后无法接收消息问题
检查kafka堆积等数
./kafka-run-class.sh kafka.tools.ConsumerOffsetChecker --zookeeper localhost:2181 --group UAT_FRONT_DATA_HBASE_SAVE_CONSUMER_GROUP --topic uat-das-front-stat-topic

在这里插入图片描述
手动消费发现堆积仍在继续

Pid Offset 为Prtition 分区
logZize 为已经消费的数,总数
Lag 为堆积数
最后为消费者信息
在这里插入图片描述
检查后发现因设置partition为0
partition 0表示这个topic只有一个分区,只能被同一个组中的一个consumer消费且消费者不是他自己导致自己无法接收到消息。

解决方法:1、可添加partition分区
2、修改消费者

删除kafkatopic
首先需要执行delete后标记

./kafka-topics.sh –-zookeeper 127.0.0.1:2181 –list
./kafka-topics.sh –delete –-zookeeper ip:2181 –topic topicname
在这里插入图片描述
添加标签后根据server.properties文件中的log.dirs配置删除topic储存目录
进入zk客户端执行

./zkCli.sh
ls /brokers/topics/topicname
rmr /admin/delete_topics/topicname

注意这里有可能删除不掉,因客户端服务在持续连接该topic会导致删除不掉.
创建topic
./kafka-topics.sh –create –topic topicname –zookeeper ip:2181 –partitions 6 –replication-factor 2

例如:
./kafka-topics.sh --create --topic lichen_tes --zookeeper 10.78.104.1:2181,10.78.104.2:2181,10.78.104.3:2181 --partitions 1 --replication-factor 2

修改topic中partition
./kafka-topics.sh –alter –zookeeper ip:2181 –partitions 8 –topic topicname

检查kafka堆积等数
例如:
./kafka-run-class.sh kafka.tools.ConsumerOffsetChecker --zookeeper localhost:2181 --group UAT_FRONT_DATA_HBASE_SAVE_CONSUMER_GROUP --topic uat-das-front-stat-topic

手动测试消费
例如:
./kafka-console-consumer.sh --zookeeper localhost:2181 --from-beginning --topic uat-das-front-stat-topic --property group.id=UAT_FRONT_DATA_HBASE_SAVE_CONSUMER_GROUP

生产者测试发送消息
例如:
./kafka-console-producer.sh --broker-list 10.78.104.1:9092 --topic lichen1
在这里插入图片描述

消费者消费
例如:
./kafka-console-consumer.sh --zookeeper localhost:2181 --from-beginning --topic lichen1
在这里插入图片描述

明白了!你发送 Kafka 消息的一方,而是**接收外部服务通过 Kafka 发送消息结果**,然后根据这个结果去更新本地数据库中的记录问题核心在于: > **外部服务在完成处理后发送 Kafka 消息,而你的服务在 Kafka 消费端尝试更新数据库记录时,本地事务还未提交(插入记录的操作还没落库),导致更新失败。** --- ### ✅ 问题本质: 外部 Kafka 消息到达太快,**早于你本地事务提交**,此时本地数据库中记录尚未提交或尚未存在,导致更新失败。 --- ### ✅ 解决方案 #### ✅ 方案一:**Kafka 消费端增加重试机制** - 如果更新失败,说明记录还未落库,可以稍后重试。 - 可以使用 Spring Retry、Spring Kafka 的重试模板(`RetryingMessageListenerAdapter`)等。 ##### 示例: ```java @Retryable(maxAttempts = 5, backoff = @Backoff(delay = 2000)) public void handleResult(String recordId) { OperationRecord record = operationRecordRepository.findById(recordId) .orElseThrow(() -> new RetryException("Record not found yet")); record.setResult("SUCCESS"); operationRecordRepository.save(record); } ``` #### ✅ 方案二:**Kafka 消费端做幂等处理** - 即使消息早到,也可以将消息缓存到内存队列或临时表中,等本地事务提交后再处理。 - 例如:使用 Redis 或本地缓存暂存 Kafka 消息,定时重试处理。 #### ✅ 方案三:**让外部服务延迟发送 Kafka 消息** - 如果你对上游服务有控制权,可以让它在确认你完成操作后再发送 Kafka 消息。 - 或者使用“异步确认机制”,即你完成插入后通知外部服务可以发送 Kafka 消息。 #### ✅ 方案四:**记录状态 + 定时补偿任务** - 插入记录时标记为 `PENDING`。 - Kafka 消费端如果找记录记录一个“待处理表”中。 - 使用定时任务定期扫描“待处理表”,尝试更新主表状态。 --- ### ✅ 总结建议: | 方案 | 是否推荐 | 说明 | |------|----------|------| | Kafka 消费端重试 | ✅ 推荐 | 简单有效,适合大多数场景 | | 缓存 Kafka 消息 | ✅ 推荐 | 更加健壮,适合高并发场景 | | 外部延迟发送 | ⚠️ 可选 | 依赖外部服务配合 | | 定时补偿任务 | ✅ 推荐 | 作为兜底策略非常实用 | --- ### ✅ 建议组合使用: - **消费端重试 + 定时补偿机制**,确保即使 Kafka 消息早到,也能最终完成更新。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值