我是Avro和Kafka的新手,他花了最后几天发送有关Kafka主题的序列化数据......但未成功。
让我解释一下我想要实现的目标:
在生产者方面,我通过SOAP接收数据并在Kafka主题上发送内容。我使用CXF从WSDL生成POJO,并且我已经编写了相应的模式。 我想要做的是序列化由CXF解组的对象并将它们发送到我的Kafka主题上。
在网络上发现的大多数示例中,Avro记录是使用已知的架构(或数据类型)生成的,但在这种情况下,我不知道在序列化数据时将使用哪个架构。 所以我动态地获取消息类型(通过CXF拦截器)并以这种方式序列化:
// get unmarshaled POJO
MessageContentsList objs = MessageContentsList.getContentsList(message);
Object obj = objs.get(0);
EncoderFactory factory = EncoderFactory.get();
ByteArrayOutputStream out = new ByteArrayOutputStream();
Encoder encoder = factory.directBinaryEncoder(out, null);
// getting schema from class name (first approach)
String scName = obj.getClass().getSimpleName();
InputStream avroRes = this.getClass().getClassLoader().getResourceAsStream(scName);
Schema schema = new Schema.Parser().parse(avroRes);
ReflectDatumWriter<Object> writer = new ReflectDatumWriter<Object>(schema);
writer.write(obj, encoder);
encoder.flush();
out.close();
KeyedMessage< String, byte[]> kMessage = new KeyedMessage<String, byte[]>("mytopic", out.toByteArray());
producer.send(kMessage);
这样我可以发送有关我主题的数据,但我无法从传入的消息中获取模式。
有办法:
什么是最好的&#34;在数据类型未知时发送关于Kafka主题的Avro记录的做法?
也许我在阅读Avro文档时遗漏了一些内容,并且没有按预期使用它。
感谢您的帮助......
答案 0 :(得分:1)
发送到Kafka主题的消息应该对架构和Avro记录进行编码。如果在每个消息中发送模式的开销太大,则发送模式的标识符。消息使用者可以使用标识符从schema registry检索完整的模式定义。例如,此code to serialize a Kafka message将模式标识符写入消息的第一个字节:
ByteArrayOutputStream out = new ByteArrayOutputStream();
schema = getSchema(object);
int id = schemaRegistry.register(subject, schema);
out.write(MAGIC_BYTE);
out.write(ByteBuffer.allocate(idSize).putInt(id).array());
BinaryEncoder encoder = encoderFactory.directBinaryEncoder(out, null);
DatumWriter<Object> writer;
if (object instanceof SpecificRecord) {
writer = new SpecificDatumWriter<Object>(schema);
} else {
writer = new GenericDatumWriter<Object>(schema);
}
writer.write(object, encoder);
encoder.flush();
byte[] bytes = out.toByteArray();
out.close();
return bytes;