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

使用SpecificAvroSerde读取Kafka事件时报Avro反序列化异常如何解决?

异常引发原因

该异常本质是Avro SpecificRecord反序列化时无法匹配写入端(Writer)Schema中指定的类型,核心触发逻辑如下:

'org.apache.kafka.common.errors.SerializationException: Error deserializing Avro message for id 4494 Caused by: org.apache.kafka.common.errors.SerializationException: Could not find class topLevelRecord specified in writer's schema whilst finding reader's schema for a SpecificRecord.'

  • 上游生产端序列化消息时使用的Schema根类型名称为topLevelRecord,和你本地用于反序列化的VertexTransactionRawEventValue类对应的Schema根类型名称、命名空间不匹配。SpecificRecord反序列化要求Writer Schema指定的类全限定名和本地存在的SpecificRecord实现类完全一致,找不到对应类就会抛出该异常。
  • GenericRecord可以正常读取的原因是它不需要绑定具体Java类,会直接从Schema Registry拉取对应id的Schema动态解析数据,不需要查找本地类。
  • 常见的触发场景包括:生产端直接动态构造Schema序列化(没有使用预生成的Specific类,默认根名称为topLevelRecord)、本地生成Specific类的Schema和Schema Registry中id为4494的Schema不一致、本地类路径下缺少对应类型的实现类。
解决方案

你可以根据实际场景选择以下任意方案解决:

  • 方案1:对齐上下游Schema
    从Schema Registry拉取id为4494的Schema文件,使用avro-maven-plugin/gradle-avro-plugin等工具重新生成本地SpecificRecord类,替换当前的VertexTransactionRawEventValue,保证生成类的全限定名和Schema中namespace+name属性完全一致。
    原有Serde配置不需要修改,保持如下即可:
    final Map<String, String> schemaMap = Collections.singletonMap(AbstractKafkaAvroSerDeConfig.SCHEMA_REGISTRY_URL_CONFIG, schemaServerURL);
    final SpecificAvroSerde<VertexTransactionRawEventValue> vertexTransactionRawEventValueAvroSerde = new SpecificAvroSerde<>();
    vertexTransactionRawEventValueAvroSerde.configure(schemaMap, false);
    KStream<String, VertexTransactionRawEventValue> vertexTransactionRawEventValueKStream =
                streamsBuilder.stream(vertexTransactionRawEventTopic,Consumed.with(Serdes.String(), vertexTransactionRawEventValueAvroSerde));
    
  • 方案2:指定Reader Schema兼容反序列化
    如果无法修改本地类,且本地VertexTransactionRawEventValue的Schema和Writer Schema是向前兼容的,可以在Serde配置中指定Reader Schema,开启Avro Schema演化能力:
    final Map<String, Object> schemaMap = new HashMap<>();
    schemaMap.put(AbstractKafkaAvroSerDeConfig.SCHEMA_REGISTRY_URL_CONFIG, schemaServerURL);
    schemaMap.put(KafkaAvroDeserializerConfig.READER_SCHEMA_CONFIG, VertexTransactionRawEventValue.getClassSchema());
    schemaMap.put(KafkaAvroDeserializerConfig.SPECIFIC_AVRO_READER_CONFIG, true);
    final SpecificAvroSerde<VertexTransactionRawEventValue> vertexTransactionRawEventValueAvroSerde = new SpecificAvroSerde<>();
    vertexTransactionRawEventValueAvroSerde.configure(schemaMap, false);
    
  • 方案3:手动转换GenericRecord
    如果上下游Schema无法对齐,可以继续使用GenericRecord接收消息,之后手动把字段映射为VertexTransactionRawEventValue对象即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 13:00:05