private KafkaTemplate<String, Object> kafkaTemplate;
……
……
//发送消息,回调结果
ListenableFuture<SendResult<String, Object>> future = kafkaTemplate.send(topic, obj);
追踪send方法后,我们将目标锁定在一个doSend方法身上。
protected ListenableFuture<SendResult<K, V>> doSend(final ProducerRecord<K, V> producerRecord) {
if (this.transactional) {
Assert.state(inTransaction(),
"No transaction is in process; "
-
"possible solutions: run the template operation within the scope of a "
-
"template.executeInTransaction() operation, start a transaction with @Transactional "
-
"before invoking the template method, "
-
“run in a transaction started by a listener container when consuming a record”);
}
final Producer<K, V> producer = getTheProducer();
this.logger.trace(() -> "Sending: " + producerRecord);
final SettableListenableFuture<SendResult<K, V>> future = new SettableListenableFuture<>();
producer.send(producerRecord, buildCallback(producerRecord, producer, future));
if (this.autoFlush) {
flush();
}
this.logger.trace(() -> "Sent: " + producerRecord);
return future;
}
这段代码的核心是下面这行代码:
producer.send(producerRecord, buildCallback(producerRecord, producer, future));
它首先构造了一个Producer对象,这个Producer是一个接口类,KafkaProducer实现了这个接口,所以此处的Producer对象即为本文的重点内容——KafkaProducer。接着这个producer调用了一个极为重要的send方法,它的第二个参数buildCallback方法返回的是一个Callback接口,用于异步回调结果。本文将围绕KafkaProducer的构造及这个send方法进行分析。
下面我们将从这行代码正式进入生产者的源码探析!!
一、KafkaProducer构造函数
===================
下面是KafkaProducer的构造方法的部分核心源码,先来简单的看看KafkaProducer构造生产者对象时都干了些什么:首先利用参数中的配置信息创建了配置对象,接着利用这个配置对象获取到了partitioner(分区器)、keySerializer(key序列化器)、valueSerializer(value序列化器)、interceptors(拦截器)……,这些都是KafkaProducer类的私有常量,后面都会用到它们;接着创建RecordAccumulator(消息收集器),后面KafkaProducer调用send方法后会用将消息数据存入其中;再然后创建更新Kafka集群的元数据;最后通过newSender()方法创建Sender线程并启动。
KafkaProducer(Map<String, Object> configs,
Serializer keySerializer,
Serializer valueSerializer,
ProducerMetadata metadata,
KafkaClient kafkaClient,
ProducerInterceptors interceptors,
Time time) {
//创建生产者配置对象
ProducerConfig config = new ProducerConfig(ProducerConfig.addSerializerToConfig(configs, keySerializer,
valueSerializer));