繁体   English   中英

Java/Quarkus Kafka 流式读取/写入基于条件的同一主题

[英]Java/Quarkus Kafka Streams Reading/Writing to Same Topic based on a condition

您好,我有这个问题正在尝试解决。 基本上,我有一个 Kafka Streams 拓扑,它将读取来自 Kafka 主题的 JSON 消息,并且该消息被反序列化为 POJO。 然后理想情况下,它将读取某个 boolean 标志的检查消息。 如果该标志为真,它将进行一些转换,然后将其写回主题。 但是,如果标志是假的,我试图让它不写任何东西,但我不确定我怎么能 go 关于它。 使用 MP Reactive Messaging 我可以只使用 RxJava 2 Flowable Stream 并返回类似 Flowable.empty() 但我不能在这里使用该方法似乎。

JsonbSerde<FinancialMessage> financialMessageSerde = new JsonbSerde<>(FinancialMessage.class);

StreamsBuilder builder = new StreamsBuilder();

builder.stream(
        TOPIC_NAME,
        Consumed.with(Serdes.Integer(), financialMessageSerde)
    )
    .mapValues ( 
        message -> checkCondition(message)
    )
    .to (
        TOPIC_NAME,
        Produced.with(Serdes.Integer(), financialMessageSerde)
    );

下面是 function 调用逻辑。

public FinancialMessage checkCondition(FinancialMessage rawMessage) {
    FinancialMessage receivedMessage = rawMessage;

    if (receivedMessage.compliance_services) {
        receivedMessage.compliance_services = false;

        return receivedMessage;
    }

    else return null;
}

如果 boolean 为假,它只会返回一个带有“null”的 JSON 主体。

我试过改变 checkCondition function 的返回类型

public Flowable<FinancialMessage> checkCondition (FinancialMessage rawMessage) 

然后从 if 返回就像 Flowable.just(receivedMessage) 或 Flowable.empty() 但我似乎无法序列化 Flowable object。 这可能是一个愚蠢的问题,但有没有更好的方法来 go 关于这个?

请注意,Kafka 消息是不可变的,并且在读取后不会被删除,如果您使用单个应用程序从同一主题读取/写入,则消息将被无限频繁地处理(或者更准确地说是它的不同副本),如果您不这样做有条件“打破”循环。

此外,例如,如果从同一主题读取 5 个服务,则所有 5 个服务都会获得每个事件的副本。 如果一个服务回写,所有其他 4 个服务和写服务本身将再次读取消息。 因此,你得到了相当多的数据放大。

如果您有不同的服务来连续地对原始输入消息做出反应,那么您可以在每对连续服务之间设置一个主题来真正构建管道。

最后,您说如果 boolean 标志为true ,您希望转换消息并发出(我假设为消费者提供下一个服务)。 而对于false你什么也不想做。 我进一步假设对于一条消息,只有一个标志为true ,并且成功的转换也会切换标志(以启用下一个服务的处理)。 对于这种情况,最好确保每个原始输入消息都设置了相同的初始 boolean 标志来构建您的管道。 因此,只有相应的服务会读取设置了 boolean 标志的消息(您甚至不需要检查 boolean 标志,因为上游写入确保它已设置;您只能进行健全性检查)。

如果您不知道最初设置了哪个 boolean 标志并且所有服务都从同一个输入主题读取,则仅过滤掉消息是正确的。 如果所有服务都读取了所有消息,则 4 个服务将过滤该消息,而一个服务将处理它并发出带有不同标志的新消息。 对于此架构,单个主题可能有效:如果一条消息由所有服务处理并且所有 boolean 标志为假(在所有服务处理消息之后),并且您将其写回输入主题,所有服务将删除最后一个副本正确。 然而,使用单个主题意味着大量的冗余读/写。

也许最好的架构是,拥有您的原始输入主题,并为每个服务添加一个额外的输入主题。 您还使用从原始输入主题读取的附加“调度程序”服务,并根据 boolean 标志将 KStream branches()到服务输入主题中。 这样,每个服务将只读取正确标志设置为true的消息。 此外,每个服务将在消息转换也使用branch()将其写入其他服务的输入主题,以将其写入正确的下一个服务的输入主题。 最后,您需要一个 output 主题,每个服务可以在消息完全处理后写入该主题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM