如何使用KStream发送标头

时间:2019-04-27 17:02:02

标签: apache-kafka apache-kafka-streams

我正在研究一个用例,其中创建了将数据从mongo发送到elasticsearch的管道。

Mongo-> Spring Boot-> Kafka-> Transformer(KStream)-> Kafka-> Consumer(发送到Elastic Search。)

我必须计算从Mongo到Elastic搜索的记录所花费的时间。我想到了使用Kafka标头,并继续在下一个Kafka Producer中转发其值,最后通过从当前时间戳中减去该值来进行计算。

我可以从生产者发送标头,但如何从Kafka Streams发送标头。在下面的代码中,我想发送在使用inTopic时获得的标头,然后将其发送到outTopic。

private StreamsBuilder buildStream(final String bootstrapServers, final String inTopic, final String outTopic) {
    StreamsBuilder streamsBuilder = new StreamsBuilder();
    KStream<String, String> kStream = streamsBuilder.stream(inTopic);

    kStream.filter(new Predicate<String, String>() {
        public boolean test(String s, String s2) {
            return true;
        }
    })
    .to(outTopic);
    return streamsBuilder;
}

2 个答案:

答案 0 :(得分:1)

您可以通过ProcessorContext访问处理器API中的标头,并一起使用DSL和处理器API。

我要做的是创建我的Transformer的实现,并在transform()中使用它。这个问题似乎与您的问题相似,并且有一个代码片段的答案,我认为这可能会有所帮助:Set timestamp in output with Kafka Streams

答案 1 :(得分:0)

@ cody123请使用ProcessContext并设置标头来查找代码。让我知道怎么回事。

private StreamsBuilder buildStream(final String bootstrapServers, final String inTopic, final String outTopic) {
    StreamsBuilder streamsBuilder = new StreamsBuilder();
    KStream<String, String> kStream = streamsBuilder.stream(inTopic);

    kStream.filter(new Predicate<String, String>() {
        public boolean test(String s, String s2) {
            return true;
        }
    }).process(() -> new Processor() {

        ProcessorContext context;

        @Override
        public void init(ProcessorContext context) {
          this.context = context;?
        }

        @Override
        public void process(Object key, Object value) {
            final Header header;
            try {
              header = new RecordHeader("key1",
                      new ObjectMapper().writeValueAsBytes("value1"));
              this.context.headers().add(header);
            }
            catch (Exception e) {
              if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("Could not add content type header");
              }
            }

        }

        @Override
        public void close() {

        }
      });
    .to(outTopic);
    return streamsBuilder;
}

/ *实现Header接口* /

import org.apache.kafka.common.header.Header;

public class RecordHeader implements Header {
    private Object obj;
    private byte[] bytes;
    public RecordHeader(Object p0, byte[] bytes) {
        this.obj=p0;
        this.bytes=bytes;
    }

    @Override
    public String key() {
        return obj.toString();
    }

    @Override
    public byte[] value() {
        return bytes;
    }
}