Kafka Java SimpleConsumer奇怪的编码

时间:2016-06-02 17:38:20

标签: java apache-kafka kafka-consumer-api

我试图在Kafka 9中使用SimpleConsumer来允许用户从时间偏移中重放事件 - 但是我从Kafka收到的消息是一个非常奇怪的编码:

7icf-test-testEvent.ebebf1a4.2911.431d.a138.f5d6db4647d7\�W>8������{"namespace":"test","type":"testEvent.ebebf1a4.2911.431d.a138.f5d6db4647d7","received":1464819330373,"context":{"userid":0,"username":"testUser"}}�!}�a�����{"namespace":"test","type":"testEvent.ebebf1a4.2911.431d.a138.f5d6db4647d7","received":1464819331637,"context":{"userid":1,"username":"testUser"}}���r�����{"namespace":"test","type":"testEvent.ebebf1a4.2911.431d.a138.f5d6db4647d7","received":1464819332754,"context":{"userid":2,"username":"testUser"}}��������{"namespace":"test","type":"testEvent.ebebf1a4.2911.431d.a138.f5d6db4647d7","received":1464819333868,"context":{"userid":3,"username":"testUser"}}�p=
                            ������{"namespace":"test","type":"testEvent.ebebf1a4.2911.431d.a138.f5d6db4647d7","received":1464819334997,"context":{"userid":4,"username"

使用KafkaConsumer这个消息解析得很好。这是我用来使用SimpleConsumer检索消息的代码:

    for (MessageAndOffset messageAndOffset : fetchResponse.messageSet(topic, partition)) {
        long currentOffset = messageAndOffset.offset();
        if (currentOffset < readOffset) {
            log.debug("Found an old offset - skip");
            continue;
        }

        readOffset = messageAndOffset.nextOffset();

        int payloadOffset = 14 + messageAndOffset.message().keySize(); // remove first x bytes, schema Id
        byte[] data = messageAndOffset.message().payload().array();
        byte[] realData = Arrays.copyOfRange(data, payloadOffset, data.length - payloadOffset);
        log.debug("Read " + new String(realData, "UTF-8"));
}

我添加了代码,在我不断收到关于字节太高的UTF-32错误之后跳过前x个字节,我假设这是因为Kafka会将有关消息大小的信息添加到有效负载中。这是Avro神器吗?

3 个答案:

答案 0 :(得分:0)

我从来没有找到一个好的答案 - 但我转而使用SimpleConsumer 来查询Kafka我需要的抵消(每个分区...虽然实施很差)然后使用seek(TopicPartition, offset)seekToBeginning(TopicPartition) 使用原生KafkaConsumer来检索消息。希望他们能够在本地客户端添加从下一版本中的给定时间戳检索消息的功能。

答案 1 :(得分:0)

你在找这个吗?

readOffset = messageAndOffset.nextOffset();
ByteBuffer payload = messageAndOffset.message().payload();

    if(payload == null) {
        System.err.println("Message is null : " + readOffset);
        continue;
    }

final byte[] realData = new byte[payload.limit()];
payload.get(realData);
System.out.println("Read " + new String(realData, "UTF-8"));

答案 2 :(得分:0)

您可以使用消息的时间戳(可能不是每次提交)定期记录您要提交的偏移量的分区,然后您可以在将来设置消费者偏移量。我认为这是用于生产调试。

我怀疑他们是否添加了这样的功能,考虑到卡夫卡的工作方式似乎不可行,虽然我可能会弄错,但总有天才的事情在发生。我做了伐木工作。