You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kafka生产者onCompletion()与get()方法的区别及Java使用详解

Kafka生产者:onCompletion回调与get()方法的区别及Java实现

核心区别

1. 执行模式

  • get():阻塞同步调用,调用后主线程暂停,直到Kafka返回发送结果(成功或失败)才继续执行。
  • onCompletion():异步非阻塞回调,调用send()后主线程立即继续执行,发送结果由Kafka客户端在后台线程触发回调函数处理。

2. 性能与吞吐量

  • get():每次发送都会阻塞主线程,无法并行处理消息,在高吞吐场景下会大幅降低生产者性能。
  • onCompletion():主线程无需等待,生产者可继续发送下一条消息,配合默认的batch.size(16384字节)和linger.ms(0),能充分利用批量发送优势,提升吞吐量。

3. 异常处理

  • get():会抛出InterruptedException、ExecutionException等检查型异常,必须显式捕获或声明抛出,异常直接暴露在主线程中。
  • onCompletion():异常通过回调参数exception传递,无需在主线程捕获,处理逻辑封装在回调内部,不会打断主线程流程。

4. 使用场景

  • get():适合同步发送场景,比如需要立即确认消息发送结果、依赖发送结果执行后续操作的业务(如订单创建后必须确认消息发送成功才返回成功)。
  • onCompletion():适合异步发送场景,比如日志采集、埋点上报等不依赖发送结果的业务,或需要批量高效发送消息的场景。

结合默认属性的Java实现示例

默认属性说明:acks=1(broker写入本地日志即确认)、batch.size=16384(批量发送阈值)、max.block.ms=60000(发送阻塞超时时间)、linger.ms=0(消息立即发送,不等待攒批)。

1. 使用get()方法同步获取结果

import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.clients.producer.RecordMetadata;
import java.util.Properties;

public class KafkaGetSyncExample {
    public static void main(String[] args) {
        Properties props = new Properties();
        props.put("bootstrap.servers", "localhost:9092");
        props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");

        try (KafkaProducer<String, String> producer = new KafkaProducer<>(props)) {
            ProducerRecord<String, String> record = new ProducerRecord<>("test-topic", "order-key", "order-value");
            
            // 调用get()阻塞等待发送结果,默认最多阻塞60秒
            RecordMetadata metadata = producer.send(record).get();
            
            System.out.printf("消息发送成功:主题=%s,分区=%d,偏移量=%d%n",
                    metadata.topic(), metadata.partition(), metadata.offset());
        } catch (Exception e) {
            System.err.println("消息发送失败:" + e.getMessage());
            e.printStackTrace();
        }
    }
}

2. 使用onCompletion()异步处理结果

import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.clients.producer.Callback;
import org.apache.kafka.clients.producer.RecordMetadata;
import java.util.Properties;

public class KafkaCallbackAsyncExample {
    public static void main(String[] args) {
        Properties props = new Properties();
        props.put("bootstrap.servers", "localhost:9092");
        props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");

        try (KafkaProducer<String, String> producer = new KafkaProducer<>(props)) {
            ProducerRecord<String, String> record = new ProducerRecord<>("test-topic", "log-key", "log-value");
            
            producer.send(record, new Callback() {
                @Override
                public void onCompletion(RecordMetadata metadata, Exception exception) {
                    if (exception == null) {
                        System.out.printf("异步消息发送成功:主题=%s,分区=%d,偏移量=%d%n",
                                metadata.topic(), metadata.partition(), metadata.offset());
                    } else {
                        System.err.println("异步消息发送失败:" + exception.getMessage());
                        exception.printStackTrace();
                    }
                }
            });
            
            System.out.println("主线程继续处理其他业务...");
        }
    }
}

内容的提问来源于stack exchange,提问作者Misubushi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 22:16:16