反应堆通量的条件逻辑

时间:2019-03-20 15:06:58

标签: java apache-kafka reactive-programming project-reactor

我是Reactor新手。我正在尝试开发以下应用程序逻辑:

  1. 从Kafka主题source阅读消息。
  2. 变换按摩。
  3. 将已转换的消息的子集写入新的Kafka主题target
  4. 明确确认最初从主题source读取的所有邮件的读取操作。

我发现的唯一解决方案是按如下方式重写上述业务逻辑。

  1. 从Kafka主题source阅读消息。
  2. 变换按摩。
  3. 立即确认邮件未写入主题target
  4. 过滤以上所有消息。
  5. 将其余转换后的消息写到新的Kafka主题target
  6. 明确确认这些邮件的阅读操作

实现第二种逻辑的代码如下:

receiver.receive()
        .flatMap(this::processMessage)
        .map(this::acknowledgeMessagesNotToWriteInKafka)
        .filter(this::isMessageToWriteInKafka)
        .as(this::sendToKafka)
        .doOnNext(r -> r.correlationMetadata().acknowledge());

很明显,receiver类型为KafkaReceiver,方法sendToKafka使用KafkaSender。我不喜欢的一件事是我正在使用map来确认一些消息。

有没有更好的解决方案来实现原始逻辑?

1 个答案:

答案 0 :(得分:1)

这并非完全是您的四个业务逻辑步骤,但我认为它离您想要的有点近。

您可以确认.filter之后不会写入.doOnDiscard的“已丢弃”消息...

receiver.receive()
        .flatMap(this::processMessage)
        .filter(this::isMessageToWriteInKafka)
        .doOnDiscard(ReceiverRecord.class, record -> record.receiverOffset().acknowledge())
        .as(this::sendToKafka)
        .doOnNext(r -> r.correlationMetadata().acknowledge());

注意:您将需要使用被丢弃的正确对象类型。我不知道发布者从processMessage返回的对象是哪种类型,但是我假设您可以从中获取ReceiverRecordReceiverOffset以便进行确认。

或者,您可以将filter / doOnDiscard组合成一个.handle运算符...

receiver.receive()
        .flatMap(this::processMessage)
        .handle((m, sink) -> {
            if (isMessageToWriteInKafka(m)) {
                sink.next(m);
            } else {
                m.getReceiverRecord().getReceiverOffset().acknowledge();
            }
        })
        .as(this::sendToKafka)
        .doOnNext(r -> r.correlationMetadata().acknowledge());