[英]How to do this topology in Spring Cloud Kafka Streams in function style?
var streamsBuilder = new StreamsBuilder();
KStream<String, String> inputStream = streamsBuilder.stream("input_topic");
KStream<String, String> upperCaseString =
inputStream.mapValues((ValueMapper<String, String>) String::toUpperCase);
upperCaseString.mapValues(v -> v + "postfix").to("with_postfix_topic");
upperCaseString.mapValues(v -> "prefix" + v).to("with_prefix_topic");
Topology topology = streamsBuilder.build();
我可以寫三個函數bean。 第一個 bean 將區分大小寫並將結果寫入某個主題 ('upper_case_topic')。 其他 bean 將使用此結果(來自“upper_case_topic”)並添加前綴/后綴。 但是如何在不寫入中間主題('upper_case_topic')的情況下做到這一點?
更新:這是我可能的解決方案:
@Bean
public Consumer<KStream<String, String>> process() {
return input -> {
KStream<String, String> upperCaseStream =
input.mapValues((ValueMapper<String, String>) String::toUpperCase);
upperCaseStream.mapValues(v -> v + " 111").to("new_topic_1");
upperCaseStream.mapValues(v -> v + " 222").to("new_topic_2");
};
}
這里有一些您可以嘗試的選項。
選項 1 - 使用 Spring Cloud Stream 中的StreamBridge
@Bean
public Consumer<KStream<String, String>> process() {
KStream<String, String> upperCaseString =
inputStream.mapValues((ValueMapper<String, String>)
String::toUpperCase);
upperCaseString.foreach((key, value) -> {
streamBridge.send("with_postfix_topic", value + "postfix");
streamBridge.send("with_prefix_topic", "prefix" + value);
});
}
上述方法的一方面是您需要來自 Spring Cloud Stream 的 Kafka 和 Kafka Streams 綁定器才能使其工作。 另一個問題是,當您在業務邏輯中直接發送到 Kafka 主題時,您會失去 Kafka Streams 原生提供的端到端語義。 根據您的用例,這種方法可能沒問題。
選項 2 - 在出站使用KStream[]
您通常在具有 Kafka Streams API 的分支功能的出站上使用KStream[]
,但您可以利用 Spring Cloud Stream 在分支功能之上構建的輸出綁定功能作為您用例的解決方法。 這是您可以嘗試的想法。
@Bean
public Function<KStream<String, String>, KStream<String, String>[]> process() {
return inputStream -> {
KStream<String, String> upperCaseString =
inputStream.mapValues((ValueMapper<String, String>)
String::toUpperCase);
KStream<String, String>[] kStreams = new KStream[2];
kStreams[0] = upperCaseString.mapValues(v -> v + "postfix");
kStreams[1] = upperCaseString.mapValues(v -> v + "postfix");
return kStreams;
};
}
然后你可以定義你的目的地如下:
spring.cloud.stream.bindings.process-in-0.destination: <input-topic-name>
spring.cloud.stream.bindings.process-out-0.destination: <output-topic-name>
spring.cloud.stream.bindings.process-out-1.destination: <output-topic-name>
使用這種方法,您可以從 Kafka Streams 獲得端到端的語義,因為通過 Kafka Streams 發送到 Kafka 的主題是通過KStream
在后台調用KStream
上的to
方法來KStream
的。
選項 3 - 使用函數組合
您擁有的另一個選擇是 Kafka Streams binder 中的函數組合。 請記住,此功能尚未發布,但 Binder 的最新 3.1.x/3.2.x 快照已提供此功能。 有了它,您可以定義三個簡單的函數,如下所示。
@Bean
public Function<KStream<String, String>, KStream<String, String>> uppercase() {
return inputStream -> inputStream.mapValues((ValueMapper<String, String>) String::toUpperCase);
}
@Bean
public Function<KStream<String, String>, KStream<String, String>> postfixed() {
return inputStream -> inputStream.mapValues(v -> v + "postfix");
}
@Bean
public Function<KStream<String, String>, KStream<String, String>> prefixed() {
return inputStream -> inputStream.mapValues(v -> "prefix" + v);
}
然后你可以有兩個函數組合流,如下所示:
spring.cloud.function.definition: uppercase|postfixed;uppercase|prefixed
您可以在每個組合函數綁定上設置輸入主題,如下所示。
spring.cloud.stream.bindings.uppercasepostfixed-in-0.destination=<input-topic>
spring.cloud.stream.bindings.uppercaseprefixed-in-0.destination=<input-topic>
使用這種函數組合方法,您可以從 Kafka Streams 獲得端到端的語義,並避免額外的中間主題。 但是,這里的缺點是uppercase
函數將為每個傳入記錄調用兩次。
上述方法可行,但請在將它們用於您的用例之前考慮權衡。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.