神祕的KafkaMessageListenerContainer

版本依賴

1. spring-kafka: 2.2.2

2. kafka-clients: 2.0.0

使用示例

1. 構建監聽,acknowledgingMessageListener 接口org.springframework.kafka.listener.AcknowledgingMessageListener的實現類

ContainerProperties containerProps = new ContainerProperties(kafkaTopic); 
containerProps.setAckMode(ContainerProperties.AckMode.MANUAL);
containerProps.setMessageListener(acknowledgingMessageListener);

2. 構建消費者

Map<String, Object> props = consumerProps(bootStrapServer, groupId, autoOffsetResetConfig);
DefaultKafkaConsumerFactory<Integer, String> conf = new DefaultKafkaConsumerFactory<>(props);
return new KafkaMessageListenerContainer<>(conf, containerProps);

DefaultKafkaConsumerFactory揭祕

protected KafkaConsumer<K, V> createKafkaConsumer(Map<String, Object> configs) {
   return new KafkaConsumer<>(configs, this.keyDeserializer, this.valueDeserializer);
}
@Override
public Consumer<K, V> createConsumer(@Nullable String groupId, @Nullable String clientIdPrefix,
      @Nullable String clientIdSuffix) {

   return createKafkaConsumer(groupId, clientIdPrefix, clientIdSuffix);
}

KafkaMessageListenerContainer揭祕

class KafkaMessageListenerContainer<K, V> extends AbstractMessageListenerContainer<K, V>
abstract class AbstractMessageListenerContainer<K, V>
      implements GenericMessageListenerContainer<K, V>, BeanNameAware, ApplicationEventPublisherAware
interface GenericMessageListenerContainer<K, V> extends MessageListenerContainer
interface MessageListenerContainer extends SmartLifecycle
interface SmartLifecycle extends Lifecycle, Phased

啓動流程:

AbstractMessageListenerContainer.java#start() 
--> listener/AbstractMessageListenerContainer.java#doStart() 
    --> this.listenerConsumer = new ListenerConsumer(listener, listenerType); 
---->
this.consumer =
      KafkaMessageListenerContainer.this.consumerFactory.createConsumer(
            this.consumerGroupId,
            this.containerProperties.getClientId(),
            KafkaMessageListenerContainer.this.clientIdSuffix);
-------->

while (isRunning()) {  
    try {  
       pollAndInvoke();  
    }  
    .....
    .....  
}  
    wrapUp(); 
}
this.fetcher = new Fetcher<>(
        logContext,
        this.client,
        config.getInt(ConsumerConfig.FETCH_MIN_BYTES_CONFIG),
        config.getInt(ConsumerConfig.FETCH_MAX_BYTES_CONFIG),
        config.getInt(ConsumerConfig.FETCH_MAX_WAIT_MS_CONFIG),
        config.getInt(ConsumerConfig.MAX_PARTITION_FETCH_BYTES_CONFIG),
        config.getInt(ConsumerConfig.MAX_POLL_RECORDS_CONFIG),
        config.getBoolean(ConsumerConfig.CHECK_CRCS_CONFIG),
        this.keyDeserializer,
        this.valueDeserializer,
        this.metadata,
        this.subscriptions,
        metrics,
        metricsRegistry.fetcherMetrics,
        this.time,
        this.retryBackoffMs,
        this.requestTimeoutMs,
        isolationLevel);

----> org/apache/kafka/clients/consumer/internals/Fetcher.java#fetchedRecords()
     --> int recordsRemaining = maxPollRecords;
     --> recordsRemaining -= records.size();
ConsumerRecords<K, V> records = this.consumer.poll(this.pollTimeout);
KafkaConsumer.class#poll
KafkaMessageListenerContainer.java#invokeListener(records);
invokeRecordListenerInTx(records)
doInvokeRecordListener(record, producer, iterator);
invokeOnMessage(record, producer);
doInvokeOnMessage(record);
private void doInvokeOnMessage(final ConsumerRecord<K, V> record) {
   switch (this.listenerType) {
      case ACKNOWLEDGING_CONSUMER_AWARE:
         this.listener.onMessage(record,
               this.isAnyManualAck
                     ? new ConsumerAcknowledgment(record)
                     : null, this.consumer);
         break;
      case CONSUMER_AWARE:
         this.listener.onMessage(record, this.consumer);
         break;
      case ACKNOWLEDGING:
         this.listener.onMessage(record,
               this.isAnyManualAck
                     ? new ConsumerAcknowledgment(record)
                     : null);
         break;
      case SIMPLE:
         this.listener.onMessage(record);
         break;
   }
}

 

至此,spring-kafka消費者的實現流程大致分析完成。

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章