Apache kafka 春天卡夫卡-遭遇”;Magic v0不支持记录头“;错误

Apache kafka 春天卡夫卡-遭遇”;Magic v0不支持记录头“;错误,apache-kafka,cloudera,flume,spring-kafka,Apache Kafka,Cloudera,Flume,Spring Kafka,我正在运行一个Spring启动应用程序,并且已经开始编译('org.springframework.kafka:springkafka:2.1.5.RELEASE') 我正试图反对使用此版本安装Cloudera: apachekafka版本3.0.0-1.3.0.0.p0.40版本0.11.0+kafka3.0.0+50的Cloudera发行版 我的KafkaProducerConfig类非常简单: @Configuration public class KafkaProducerConfig

我正在运行一个Spring启动应用程序,并且已经开始编译('org.springframework.kafka:springkafka:2.1.5.RELEASE')

我正试图反对使用此版本安装Cloudera:

apachekafka版本3.0.0-1.3.0.0.p0.40版本0.11.0+kafka3.0.0+50的Cloudera发行版

我的KafkaProducerConfig类非常简单:

@Configuration
public class KafkaProducerConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(KafkaProducerConfig.class);

@Value("${spring.kafka.bootstrap-servers}")
private String bootstrapServers;

@Value("${spring.kafka.template.default-topic}")
private String defaultTopicName;

@Value("${spring.kafka.producer.compression-type}")
private String producerCompressionType;

@Value("${spring.kafka.producer.client-id}")
private String producerClientId;

@Bean
public Map<String, Object> producerConfigs() {
    Map<String, Object> props = new HashMap<>();

    props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, this.bootstrapServers);
    props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
    props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class);
    props.put(ProducerConfig.COMPRESSION_TYPE_CONFIG, this.producerCompressionType);
    props.put(ProducerConfig.CLIENT_ID_CONFIG, this.producerClientId);
    props.put(JsonSerializer.ADD_TYPE_INFO_HEADERS, false);

    return props;
}

@Bean
public ProducerFactory<String, Pdid> producerFactory() {
    return new DefaultKafkaProducerFactory<>(producerConfigs());
}

@Bean
public KafkaTemplate<String, Pdid> kafkaTemplate() {
    KafkaTemplate<String, Pdid> kafkaTemplate = new KafkaTemplate<>(producerFactory());

    kafkaTemplate.setDefaultTopic(this.defaultTopicName);

    return kafkaTemplate;
}

@PostConstruct
public void postConstruct() {
    LOGGER.info("Kafka producer configuration: " + this.producerConfigs().toString());
    LOGGER.info("Kafka topic name: " + this.defaultTopicName);
}
我从生产者应用程序方面尝试了以下几点:

  • 降级为春季卡夫卡2.0.4。我原本希望使用卡夫卡版本的0.11.0可以帮助解决这个问题,但没有效果
  • 已验证所有节点都是相同的版本。据我的管理员说,他们是
  • 与我的管理员核实,我们没有混合安装。又一次,我被告知我们没有
  • 基于一个类似的堆栈溢出问题,我回到了2.1.5,并尝试将JsonSerializer.ADD_TYPE_INFO_头添加到false中。我想它可能会删除日志所引用的标题。同样,不通过,并且记录了相同的错误
  • 我希望我错过了一些明显的东西。我是否需要打开/关闭任何其他标题来帮助解决任何人都知道的Magic v0问题

    我们有其他应用程序可以在同一环境中成功地编写其他主题,但它们是手工制作必要的Springbean的较旧应用程序。此外,这些应用程序还使用了更老的客户机(0.8.2.2),并且它们使用StringSerializer作为生产者值,而不是JSON。我需要我的数据是JSON格式的,当我们在一个应该支持0.11.x的系统上时,我真的不想降级到0.8.2.2

    但它们是手工制作必要的SpringBean的较旧应用程序

    位于org.apache.kafka.common.record.FileRecordsdownConvert(FileRecords.java:245)

    我不熟悉kafka broker的内部结构,但“听起来”主题是用旧的代理创建的,它们的格式不支持头,而不支持代理版本本身(提示:downConvert)

    你有没有试过找一个干净的经纪人

    只要您不尝试使用代理不支持的功能,1.0.x客户端就可以与旧代理(回到0.10.2.x IIRC)对话。您的代理是0.11(它确实支持头文件)这一事实进一步表明,主题记录格式才是问题所在

    我已经成功地测试了up/down broker/client/topic版本,没有问题,只要您使用公共功能子集

    JsonSerializer.ADD_TYPE_INFO_头为false

    这将防止框架设置任何标题;您需要显示生产者代码(以及所有配置)

    您还可以将
    producertinterceptor
    添加到producer配置中,并检查
    onSend()
    方法中的
    ProducerRecord
    headers
    属性,以了解输出消息中的头设置


    如果您使用的是spring消息(
    template.setn(Message m)
    ,默认情况下会映射头)。使用原始
    template.send()
    方法将不会设置任何标题(除非您发送填充标题的
    ProducerRecord

    问题的解决方案是两方面的混合:

  • 我需要添加
    JsonSerializer.add\u TYPE\u INFO\u头到false
    ,就像Gary Russell建议的那样
  • 在将配置放入我的应用程序之前,我需要刷新主题中的所有记录。以前的记录都有标题,这会损坏Flume使用者

  • 我已经将我的应用程序升级到Spring boot 2x,并且我与kafka客户端依赖项存在一些兼容性问题(请参阅),因此我也必须升级它。另一方面,我有一个旧的代理(kafka 0.10)在服务器上运行,然后我无法向它发送消息。我还意识到,即使将
    JsonSerializer.ADD_TYPE_INFO_HEADERS
    设置为false,卡夫卡制作人也在内部设置了头,因为魔法是根据卡夫卡的版本(在
    RecordBatch
    中)来修复的在这种情况下,如果(magic0)抛出新的IllegalArgumentException(“magic v”+magic+“不支持记录头”);,则无法避免陷入
    MemoryRecordsBuilder.appendWithOffset

    最后,我解决这个问题的唯一方法是升级我的卡夫卡服务器。

    谢谢你的建议/澄清。我已经更新了我的原始帖子,使其具有完整的卡夫卡制作人配置,而不仅仅是我最初发布的部分。谢谢,但是
    send()
    您在模板上使用的方法是什么?我们使用的是
    kafkaTemplate.sendDefault
    one,在application.yml文件.Aha中设置了默认主题-因此
    downConvert
    是因为主题中已有消息头,但消费者不支持它们。
    [KafkaApi-131] Error when handling request {replica_id=-1,max_wait_time=500,min_bytes=1,topics=[{topic=profiles-pdid,partitions=[{partition=0,fetch_offset=7,max_bytes=1048576}]}]}java.lang.IllegalArgumentException: Magic v0 does not support record headers
    at org.apache.kafka.common.record.MemoryRecordsBuilder.appendWithOffset(MemoryRecordsBuilder.java:385)
    at org.apache.kafka.common.record.MemoryRecordsBuilder.append(MemoryRecordsBuilder.java:568)
    at org.apache.kafka.common.record.AbstractRecords.convertRecordBatch(AbstractRecords.java:117)
    at org.apache.kafka.common.record.AbstractRecords.downConvert(AbstractRecords.java:98)
    at org.apache.kafka.common.record.FileRecords.downConvert(FileRecords.java:245)
    at kafka.server.KafkaApis$$anonfun$kafka$server$KafkaApis$$convertedPartitionData$1$1$$anonfun$apply$5.apply(KafkaApis.scala:523)
    at kafka.server.KafkaApis$$anonfun$kafka$server$KafkaApis$$convertedPartitionData$1$1$$anonfun$apply$5.apply(KafkaApis.scala:521)
    at scala.Option.map(Option.scala:146)
    at kafka.server.KafkaApis$$anonfun$kafka$server$KafkaApis$$convertedPartitionData$1$1.apply(KafkaApis.scala:521)
    at kafka.server.KafkaApis$$anonfun$kafka$server$KafkaApis$$convertedPartitionData$1$1.apply(KafkaApis.scala:511)
    at scala.Option.flatMap(Option.scala:171)
    at kafka.server.KafkaApis.kafka$server$KafkaApis$$convertedPartitionData$1(KafkaApis.scala:511)
    at kafka.server.KafkaApis$$anonfun$kafka$server$KafkaApis$$createResponse$2$1.apply(KafkaApis.scala:559)
    at kafka.server.KafkaApis$$anonfun$kafka$server$KafkaApis$$createResponse$2$1.apply(KafkaApis.scala:558)
    at scala.collection.Iterator$class.foreach(Iterator.scala:891)
    at scala.collection.AbstractIterator.foreach(Iterator.scala:1334)
    at scala.collection.IterableLike$class.foreach(IterableLike.scala:72)
    at scala.collection.AbstractIterable.foreach(Iterable.scala:54)
    at kafka.server.KafkaApis.kafka$server$KafkaApis$$createResponse$2(KafkaApis.scala:558)
    at kafka.server.KafkaApis$$anonfun$kafka$server$KafkaApis$$fetchResponseCallback$1$1.apply$mcVI$sp(KafkaApis.scala:579)
    at kafka.server.ClientQuotaManager.recordAndThrottleOnQuotaViolation(ClientQuotaManager.scala:196)
    at kafka.server.KafkaApis.sendResponseMaybeThrottle(KafkaApis.scala:2014)
    at kafka.server.KafkaApis.kafka$server$KafkaApis$$fetchResponseCallback$1(KafkaApis.scala:578)
    at kafka.server.KafkaApis$$anonfun$kafka$server$KafkaApis$$processResponseCallback$1$1.apply$mcVI$sp(KafkaApis.scala:598)
    at kafka.server.ClientQuotaManager.recordAndThrottleOnQuotaViolation(ClientQuotaManager.scala:196)
    at kafka.server.ClientQuotaManager.recordAndMaybeThrottle(ClientQuotaManager.scala:188)
    at kafka.server.KafkaApis.kafka$server$KafkaApis$$processResponseCallback$1(KafkaApis.scala:597)
    at kafka.server.KafkaApis$$anonfun$handleFetchRequest$1.apply(KafkaApis.scala:614)
    at kafka.server.KafkaApis$$anonfun$handleFetchRequest$1.apply(KafkaApis.scala:614)
    at kafka.server.ReplicaManager.fetchMessages(ReplicaManager.scala:639)
    at kafka.server.KafkaApis.handleFetchRequest(KafkaApis.scala:606)
    at kafka.server.KafkaApis.handle(KafkaApis.scala:98)
    at kafka.server.KafkaRequestHandler.run(KafkaRequestHandler.scala:66)
    at java.lang.Thread.run(Thread.java:748)