我有一个kafka主题,其中包含无avro模式的消息。我们最近想使用avro模式将消息推送到该主题。
现在,该主题同时具有带/不带模式的消息。
我有一个从这个主题消费的消费者。
->如果在消费者配置中将value.deserializer
设置为“ KafkaAvroDeserializer.class
”,则看不到任何消息被消耗。
->如果在消费者配置中将value.deserializer
设置为“ StringDeserializer.class
”,则可以使用消息,但是具有avro模式的消息现在看起来已加密。
例如:ConsumerRecord(topic = sample-events, partition = 2, offset = 1089595, CreateTime = 1544116093932, checksum = 2421249481, serialized key size = -1, serialized value size = 159, key = null, value = ���test_impressLbhpb_extranet_opportunity_cleaning_fecron�����YH00756f54-ba55-11e7-8df0-fdb86cefa6ed$abcde)
。
我已经为avro模式生成了Java类,并且我希望将来自/不包含来自消费者的模式的消息投射到此生成的avro java类。我可以使用objectMapper将不带模式的消息映射到avro Java类。
但是对于来自消费者的具有avro模式的消息,如示例中所提到的,它看起来像是加密的,我正在下面的代码段中进行尝试:
SpecificDatumReader<SampleEvents> reader = new SpecificDatumReader<SampleEvents>(SampleEvents.getClassSchema());
Decoder decoder = DecoderFactory.get().binaryDecoder(new ByteArrayInputStream(record), null);
SampleEvents event = reader.read(null, decoder);
但这不起作用。我收到“错误:
java.lang.ArrayIndexOutOfBoundsException:-1“。
如何反序列化此消息?
答案 0 :(得分:0)
如果我在消费者配置中将value.deserializer设置为“ KafkaAvroDeserializer.class”,则看不到任何消息被消耗。
嗯,您至少应该收到HTTP或反序列化器错误...
首先,您应该使用BytesDeserializer
或它的一种变体
然后,您需要熟悉ByteBuffer
的方法并将byte[]
合并为一个。...
如果您具有 Schema Registry编码 Avro消息,则这些消息具有well-defined wire format
因此,您可能会遇到类似以下内容的问题,但最后,它需要对主题中可能包含哪些数据进行一些推断。
// consumerConfig.put("value.deserializer", ByteBufferDeserializer.class)
ByteBuffer buf = record.value();
Deserializer d;
if (buf == null) {
System.err.println("Tombstoned record");
} else if (buf.get() == 0x0) { // Check for Avro
int schemaId = buf.getInt(); // If you wanted it
d = new KafkaAvroDeserializer();
Map<String, String> config = new HashMap<>();
config.put("schema.registry.url", "http://..."); // address to registry
boolean isKey = false;
d.configure(config, isKey);
AvroValue v = d.deserialize(value);
// TODO: Handle record
} else {
try {
d = new StringDeserializer();
String s = d.deserialize(value);
// TODO: Handle record
} catch (Exception e) {
e.printStackTrace();
}
}
摘录:不要将Avro和非Avro数据类型转换为主题。否则,您只需要消耗字节并自己处理自定义逻辑。