Java 8 Stream是我正在寻找的解决方案吗?

时间:2018-12-12 19:32:34

标签: java mongodb collections apache-kafka

我正在构建一个工具,用于从Kafka消费数据并将其插入MongoDB,并在它们之间进行一些操作。

现在我正在做:

// Poll during X ms
ConsumerRecords<String, String> records = consumer.poll(Duration.of(100, ChronoUnit.MILLIS));
// For each record, insert it into Mongo
for (ConsumerRecord<String, String> record : records) {
  System.out.println("Message of length ["+ record.value().length() +"] received.");
  Tools._insertReport(record.value());
}

我正在寻找诸如动态集合之类的解决方案,在其中可以堆积记录,而insert方法将插入然后从堆积中移除记录,这是怎么回事?就像内部消息队列一样。

Java 8 Streams是这样的吗?如果没有,有什么明显的解决方案吗?

编辑1:

两种解决方案似乎都是可行的。 Kafka Connector和RxJava,由于RxJava看起来更像我要找的东西,因此我将在此处研究并发表研究结果。谢谢你们。

3 个答案:

答案 0 :(得分:1)

我不知道您到底想要实现什么,但是为了从Kafka中读取消息并将其写入MongoDB中,建议您将Kafka Connect与mongoDB连接器配合使用! 所有排队都由kafka connect本地完成,无需编写代码。

您会发现许多适合您情况的mongodb连接器,这里有两个:

https://github.com/hpgrahsl/kafka-connect-mongodb/blob/master/README.md

https://docs.lenses.io/connectors/sink/mongo.html

后者可能是首先尝试的不错选择,它使用起来更简单,并且镜头管理着其他几个连接器。

答案 1 :(得分:0)

  

Java 8是否流过类似的内容?

不是,不是。

一种明显的解决方案是从字面上创建一个固定大小的List<ConsumerRecord>,然后定期检查该列表的大小...填满后,循环并刷新到Mongo,否则您将一次执行一次记录。

不过,可以选择使用Kafka Connect,因为它可以更合理的方式管理异常,重试和消息转换。

答案 2 :(得分:0)

是的,Streams根本不是,但是RxJava是用例的合适答案。更确切地说,发布主题是。

我创建了一个类,启动了所说的发布主题,然后使用.onNext()函数将我的Kafka ConsumerRecord传递给主题。这是定义:

public static void _initRx(){
        RxRecordsList = PublishSubject.create();
        RxRecordsList.subscribe(_initRxRecordConsumer());
    }
    private static Observer<ConsumerRecord<String,String>> _initRxRecordConsumer(){
        return new Observer<ConsumerRecord<String,String>>() {
            @Override
            public void onSubscribe(Disposable d) {
                System.out.println("Rx Subscrition : OK");
            }

            @Override
            public void onNext(ConsumerRecord record) {
                System.out.println("Message received - Length : "+record.toString().length());
                MongoHelper._insertReport(record.value().toString());
            }

            @Override
            public void onError(Throwable e) {
                System.out.println("Error: "+ e);
            }

            @Override
            public void onComplete() {
                System.out.println("Stream ended");
            }
        };
    }

这是我将数据推送到其中的方法:

while(true) {
  ConsumerRecords<String, String> records = consumer.poll(Duration.of(100, ChronoUnit.MILLIS));
  for (ConsumerRecord<String, String> record : records) {
    RxHDB_Records.RxRecordsList.onNext(record);
  }
}

我不知道它是否做得很好,但它的工作原理如此……这是一个开始。我不知道如何使用运算符或如何从此处更改日期类型。但这仍然是一个开始