首页/数据/数据工程与 ETL 速查/Java 消费者代码示例
Kafka64 条

Java 消费者代码示例

Java 消费者骨架:关闭自动提交、poll 循环处理、按批手动提交;poll 间隔内的处理时长要控制在 max.poll.interval.ms 内。

Java 消费者骨架

Java 消费者的基本结构是一个永不退出的 poll 循环:每一轮 poll 拉回一批记录,处理完再提交位移。位移提交时机直接决定语义——先提交后处理会丢消息,先处理后提交会重复消费,所以骨架里通常关闭自动提交、改成处理成功后手动提交。另外,两次 poll 之间的时间必须小于 max.poll.interval.ms,否则消费者会被踢出组并触发再均衡。

基本信息

订阅方式subscribe 走组协调;assign 手动指定分区
位移提交处理成功后 commitSync/commitAsync
退出方式wakeup() 打断阻塞的 poll 后 close()
关键配置group.id、key/value.deserializer、enable.auto.commit
并行度上限组内消费者数超过分区数时多余的实例空转
线程模型Consumer 非线程安全,一个实例只在一个线程里使用

最小示例

最小示例
Properties props = new Properties();
props.put("bootstrap.servers", "kafka1:9092");
props.put("group.id", "order-consumer");
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("enable.auto.commit", "false");

KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
consumer.subscribe(Collections.singletonList("orders"));
while (true) {
    ConsumerRecords<String, String> records = consumer.poll(Duration.ofSeconds(1));
    for (ConsumerRecord<String, String> r : records) {
        process(r);
    }
    consumer.commitSync();   // 处理完成后再提交,失败可重放
}

典型使用场景

  • 事件驱动业务:消费订单或支付事件触发下游动作
  • 数据入仓:把消息批量写入数据库或对象存储
  • 多实例并行:靠分区数决定并行上限,扩容前先确认分区是否够用
  • 需要至少一次语义:处理成功再提交,下游接口做幂等
  • 暂停与恢复:临时下游故障时 pause 分区,恢复后 resume 继续

关键配置读法

配置作用注意
enable.auto.commit是否自动提交位移关闭后需自行控制提交时机
auto.offset.reset无位点或位点失效时的起始位置一般用 earliest 或 latest
max.poll.records单次拉取条数直接决定一轮处理时长
max.poll.interval.ms两次 poll 的最大间隔超时会被踢出组
fetch.min.bytes单次拉取的最小数据量调大可提高吞吐但增加延迟
poll 循环里做同步外部调用(长 SQL、慢接口)会阻塞心跳之外的处理进度,容易触发再均衡。
位移提交策略决定了故障时的行为:处理成功后提交是至少一次(可能重复),先提交再处理是至多一次(可能丢),需要精确一次时通常要配合下游幂等或事务。

易错点

  • commitSync 放在循环外按批提交,崩溃时整批重放,下游需幂等
  • 异常处理吞掉错误继续循环,会造成「看起来在消费、实际一直失败」
  • 多线程共享一个 Consumer 实例,会触发并发访问异常
  • consumer 实例数超过分区数,多余实例分不到分区却仍占资源
  • 位移提交与业务写入不在同一事务里,两边状态可能长期不一致

数据来源与参考

  • Apache Kafka 官方文档:Consumer API 使用示例
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌