使用Apicurio Schema Registry进行序列化时,如何指定正确的Group ID以解决工件找不到的错误?
看起来你遇到的问题是Apicurio的Serdes组件没有正确读取你配置的显式Group ID,导致它默认用null去查找工件。结合你使用的2.6.8.Final版本,我来帮你梳理下解决思路和具体方案:
问题根源分析
从报错No artifact with ID 'test-samuel-value' in group 'null' was found来看,你的Serde并没有正确加载到default这个Group ID配置,大概率是配置传递方式有问题,或者多配置项的优先级导致逻辑混乱。
具体解决步骤
1. 简化配置,避免参数冲突
你同时配置了Fallback和Explicit两类参数,这可能让Serdes的配置逻辑出现优先级混乱。先尝试移除Fallback相关配置,只保留显式指定的核心项,确保逻辑清晰:
properties.put(SerdeConfig.EXPLICIT_ARTIFACT_ID, "test-samuel-value"); properties.put(SerdeConfig.EXPLICIT_ARTIFACT_GROUP_ID, "default"); // 务必加上Registry地址配置,确保Serde能连接到你的Registry实例 properties.put(SerdeConfig.REGISTRY_URL_CONFIG, "http://你的ApicurioRegistry地址:8080/apis/registry/v2");
2. 确保配置正确传递给Serializer实例
很多开发者会犯的错误是把Serde配置只放到Kafka Producer的通用Properties里,而没有传递给具体的Serializer。正确的做法是把Serde配置单独传给AvroSerializer的configure方法:
// 1. 准备Serde专属配置 Map<String, Object> serdeProps = new HashMap<>(); serdeProps.put(SerdeConfig.EXPLICIT_ARTIFACT_ID, "test-samuel-value"); serdeProps.put(SerdeConfig.EXPLICIT_ARTIFACT_GROUP_ID, "default"); serdeProps.put(SerdeConfig.REGISTRY_URL_CONFIG, "http://你的ApicurioRegistry地址:8080/apis/registry/v2"); // 2. 初始化并配置Avro序列化器 AvroSerializer<你的Avro实体类> valueSerializer = new AvroSerializer<>(); // 第二个参数为false表示这是value的序列化器(true是key) valueSerializer.configure(serdeProps, false); // 3. 创建Kafka Producer时传入配置好的Serializer实例 Map<String, Object> producerProps = new HashMap<>(); producerProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "你的KafkaBroker地址:9092"); producerProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); // 注意:这里直接传入配置好的valueSerializer,而不是只指定类名 KafkaProducer<String, 你的Avro实体类> producer = new KafkaProducer<>( producerProps, new StringSerializer(), valueSerializer );
3. 验证配置是否生效(排查用)
如果还是有问题,可以在配置Serializer后打印配置值,确认Group ID是否被正确加载:
System.out.println("加载的显式Group ID:" + serdeProps.get(SerdeConfig.EXPLICIT_ARTIFACT_GROUP_ID)); System.out.println("加载的显式Artifact ID:" + serdeProps.get(SerdeConfig.EXPLICIT_ARTIFACT_ID));
如果输出不是default和test-samuel-value,说明配置没有被正确读取,可能是常量引用错误,此时可以尝试直接用字符串配置键代替常量:
serdeProps.put("apicurio.registry.explicit.artifact.group.id", "default"); serdeProps.put("apicurio.registry.explicit.artifact.id", "test-samuel-value");
4. 确认Registry中的工件存在性
最后再检查一遍Apicurio Registry的UI:确认在default分组下,确实存在ID为test-samuel-value的工件,且工件状态是“已启用”的。
你的依赖版本说明
你使用的Apicurio依赖版本是2.6.8.Final,完全兼容上述方案:
<dependency> <groupId>io.apicurio</groupId> <artifactId>apicurio-registry-serdes-avro-serde</artifactId> <version>2.6.8.Final</version> </dependency> <dependency> <groupId>io.apicurio</groupId> <artifactId>apicurio-registry-app</artifactId> <version>2.6.8.Final</version> </dependency>
备注:内容来源于stack exchange,提问作者Samuel Holmes

