无待处理的回复:ConsumerRecord

时间:2018-12-12 22:44:08

标签: java apache-kafka spring-kafka

我正在尝试使用ReplyingKafkaTemplate,并且间歇性地继续看到以下消息。

  

没有待处理的回复:ConsumerRecord(topic = request-reply-topic,   分区= 8,偏移= 1,CreateTime = 1544653843269,序列化密钥   size = -1,序列化值size = 1609,标头=   RecordHeaders(headers = [RecordHeader(key = kafka_correlationId,值   = [-14,65,21,-118,70,-94,72,87,-113,-91,92,72,-124,-110,-64,-94])],isReadOnly = false) ,键=空,相关性ID:[-18271255759235816475365319231847350110],可能超时,或者使用   共享的回复主题

它源自下面的代码

RequestReplyFuture<K, V, R> future = this.futures.remove(correlationId);
if (future == null) {
  if (this.sharedReplyTopic) {
    if (this.logger.isDebugEnabled()) {
      this.logger.debug(missingCorrelationLogMessage(record, correlationId));
    }
  }
  else if (this.logger.isErrorEnabled()) {
    this.logger.error(missingCorrelationLogMessage(record, correlationId));
  }
}

但只是偶尔发生

我还按如下所示将共享的ReplyTopic设置为false,并试图强制延长超时时间

ReplyingKafkaTemplate<String, Object, Object> replyKafkaTemplate = new ReplyingKafkaTemplate<>(pf, container);
        replyKafkaTemplate.setSharedReplyTopic(false);
        replyKafkaTemplate.setReplyTimeout(10000);
        return replyKafkaTemplate;

我的容器如下

@Bean
public KafkaListenerContainerFactory<ConcurrentMessageListenerContainer<String, Object>> kafkaListenerContainerFactory() {
    ConcurrentKafkaListenerContainerFactory<String, Object> factory = new ConcurrentKafkaListenerContainerFactory<>();
    factory.setConsumerFactory(consumerFactory());

    factory.setBatchListener(false);
    factory.getContainerProperties().setPollTimeout(1000);
    factory.getContainerProperties().setIdleEventInterval(10000L);
    factory.setConcurrency(3);
    factory.setReplyTemplate(kafkaTemplate());
    return factory;
}

1 个答案:

答案 0 :(得分:0)

如果它是断断续续的,则很可能是回复花了太长时间才能到达。消息似乎很清楚

  

可能超时,或使用共享回复主题

每个客户端实例必须使用其自己的回复主题或专用分区。

编辑

如果收到的消息的相关性ID与this.futures中的当前条目不匹配(待答复),则会得到日志。这只能在以下情况下发生:

  1. 请求超时(在这种情况下,将有一个对应的WARN日志)。
  2. 对模板进行stop()操作(在这种情况下,将清除this.futures)。
  3. 由于某些原因(不应发生)重新发送已经处理过的回复。
  4. 在将密钥添加到this.futures之前已收到答复。(因为它是在send()保存记录之前插入的,所以不会发生。)
  5. 服务器端针对同一请求发送2个或更多回复。
  6. 其他一些应用程序正在将数据发送到相同的答复主题。如果您可以使用DEBUG日志重现它,那么它将有所帮助,因为然后我们还将相关密钥也记录在发送中。