Kotlin SpringCloudStream生成了不必要的复杂卡夫卡拓扑,为什么?
我有一个KStream应用程序,其中包含一系列KStream、join和其他操作。我启用了Kotlin SpringCloudStream生成了不必要的复杂卡夫卡拓扑,为什么?,kotlin,apache-kafka,spring-cloud,apache-kafka-streams,spring-cloud-stream,Kotlin,Apache Kafka,Spring Cloud,Apache Kafka Streams,Spring Cloud Stream,我有一个KStream应用程序,其中包含一系列KStream、join和其他操作。我启用了logging.level.org.springframework.kafka.config=debug来验证正在生成的拓扑,并发现了许多毫无意义的节点 然后,我将应用程序简化为: interface ShippingKStreamProcessor { @Input("input") fun input(): KStream<Int, Customer> } @Suppr
logging.level.org.springframework.kafka.config=debug
来验证正在生成的拓扑,并发现了许多毫无意义的节点
然后,我将应用程序简化为:
interface ShippingKStreamProcessor {
@Input("input")
fun input(): KStream<Int, Customer>
}
@Suppress("UNCHECKED_CAST")
@Configuration
class ShippingKStreamConfiguration {
@StreamListener
fun process(@Input("input") input: KStream<Int, Customer> {}
}
Spring Cloud Stream生成如此复杂拓扑的原因是什么?@codependent拓扑中有这些额外处理器的原因是因为您使用的是框架提供的de/serailzers(本机解码和编码默认为
false
)。基本上,我们从Kafka topic以字节[]
的形式接收数据,然后在内部进行转换。对于这些转换,我们需要使用一些额外的处理器,因此最终会得到更深层次的拓扑结构
下面是Java中的一个基本的StreamListener
(与上面的内容基本相同,但使用的是更简单的值类型):
我的拓扑结构简化如下:
2019-05-01 18:02:12.705 DEBUG 67539 --- [ main] o.s.k.config.StreamsBuilderFactoryBean : Topologies:
Sub-topology: 0
Source: KSTREAM-SOURCE-0000000000 (topics: [hello-1])
--> KSTREAM-MAPVALUES-0000000001
Processor: KSTREAM-MAPVALUES-0000000001 (stores: [])
--> none
<-- KSTREAM-SOURCE-0000000000
2019-05-01 18:02:12.705调试67539---[main]o.s.k.config.StreamsBuilderFactoryBean:拓扑:
子拓扑:0
来源:KSTREAM-Source-0000000000(主题:[hello-1])
-->KSTREAM-MAPVALUES-000000000 1
处理器:KSTREAM-MAPVALUES-000000000 1(存储:[])
-->没有
这很有趣。我会调查的。我能想到的一个原因是绑定器需要进行消息转换。因此,如果您可以启用本机解码/编码,我认为这将稍微减少拓扑结构。除此之外,绑定器还可以在其他路径中添加更多拓扑,例如使用DLQ等。从Spring Cloud Stream Kafka Streams绑定器的3.0版本开始,默认的反序列化由Kafka本机完成。因此,Spring应用程序生成的拓扑相当于本机应用程序生成的拓扑。
fun main(args: Array<String>) {
val builder = StreamsBuilder()
val streamsConfiguration = Properties()
streamsConfiguration[StreamsConfig.APPLICATION_ID_CONFIG] = "kafka-shipping-service"
streamsConfiguration[StreamsConfig.BOOTSTRAP_SERVERS_CONFIG] = "http://localhost:9092"
streamsConfiguration[AbstractKafkaAvroSerDeConfig.SCHEMA_REGISTRY_URL_CONFIG] = "http://localhost:8081"
val serdeConfig = mapOf(
AbstractKafkaAvroSerDeConfig.SCHEMA_REGISTRY_URL_CONFIG to "http://localhost:8081",
AbstractKafkaAvroSerDeConfig.VALUE_SUBJECT_NAME_STRATEGY to TopicRecordNameStrategy::class.java.name
)
//val byteArraySerde = Serdes.ByteArray()
val intSerde = Serdes.IntegerSerde()
val customerSerde = SpecificAvroSerde<Customer>()
customerSerde.configure(serdeConfig, false)
val customerStream = builder.stream<Int, Customer>("customer",
Consumed.with(intSerde, customerSerde)) as KStream<Int, Customer>
val topology = builder.build()
println(topology.describe())
val streams = KafkaStreams(topology, streamsConfiguration)
streams.start()
}
Topologies:
Sub-topology: 0
Source: KSTREAM-SOURCE-0000000000 (topics: [customer])
--> none
@StreamListener
public void process(@Input("input") KStream<Integer, String> input ) {
}
spring.cloud.stream.kafka.streams:
binder.configuration:
default.key.serde: org.apache.kafka.common.serialization.Serdes$IntegerSerde
default.value.serde: org.apache.kafka.common.serialization.Serdes$StringSerde
spring.cloud.stream.bindings.input.consumer.useNativeDecoding: true
2019-05-01 18:02:12.705 DEBUG 67539 --- [ main] o.s.k.config.StreamsBuilderFactoryBean : Topologies:
Sub-topology: 0
Source: KSTREAM-SOURCE-0000000000 (topics: [hello-1])
--> KSTREAM-MAPVALUES-0000000001
Processor: KSTREAM-MAPVALUES-0000000001 (stores: [])
--> none
<-- KSTREAM-SOURCE-0000000000