根据POJO定义架构,每个主题定义多个架构

时间:2019-12-08 15:22:26

标签: java apache-kafka avro confluent-schema-registry

现在,我们使用JSON格式向Kafka进行消息传递,现在我将使用Schema Registry将ser / deser格式更改为Avro。 也许我想要很多,但是我的要求是:

  • 不将模式存储在项目中,也不使用插件生成类 并在启动时通过ReflectData获取所有架构。
  • 每个主题保留多个架构
  • 不要在GenericRecord中反序列化并将其映射到具有反射的POJO,因为我想它会降低吞吐量
  • 不丢失兼容性功能。至少向后兼容

我做到了:

  1. 创建两个简单的POJO,它们均继承自同一抽象类BasicMessage。
  2. 覆盖this之类的KafkaAvroSerializer,以通过反射从POJO定义模式
  3. 通过配置将每个POJO发送两条消息到Kafka
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, LongSerializer.class);
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, MyCustomAvroSerializer.class);
props.put("schema.registry.url", "http://localhost:8081");
props.put("value.subject.name.strategy", TopicRecordNameStrategy.class);
  1. 重写KafkaAvroDeserializer可以从缓存schemaName-> Schema定义读取器架构,其中键是从架构注册表获取的编写者的架构名称。
  2. 使用配置消费来自Kafka的消息
props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, LongDeserializer.class);
props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, MyCustomAvroDeserializer.class);
props.put(KafkaAvroDeserializerConfig.SPECIFIC_AVRO_READER_CONFIG, true);
props.put("schema.registry.url", "http://localhost:8081");

在那种情况下,两个POJO都正确地反序列化为BasicMessage,这对我有好处。但是,然后我检查了向后兼容性-在POJO之一中添加了具有默认值的新字段,并且已经使用更新的方案再次使用了消息(它变成了读取器模式),在反序列化期间出现异常。

所以,问题是:

  1. 还有其他更好的解决方案可以解决我的要求吗?
  2. 看起来像here,该问题已解决,但在maven repo的最新版本5.3.0中,此PR不存在。这意味着它不是公开发布,需要等待吗?
  3. 如果我对here的理解正确,则不建议指定SubjectNameStrategy。那么,如何使用Avro正确处理每个主题的多个架构?通过模式联合吗?

0 个答案:

没有答案