仅在应用程序启动时实现的状态存储已完全填充并准备就绪后,Spring-Cloud-Stream才会处理kafka消息

时间:2019-05-09 09:29:28

标签: java spring-boot apache-kafka apache-kafka-streams spring-cloud-stream

请参阅此solution, 我的spring-cloud-stream application.yml文件具有以下配置:

#application.yml

spring.cloud.stream.bindings.input:
  destination: my-topic-name
  contentType: application/json
  consumer:
    useNativeDecoding: false
spring.cloud.stream.kafka.streams.bindings.input:
  consumer:
    keySerde: org.apache.kafka.common.serialization.Serdes$StringSerde
    valueSerde: org.apache.kafka.common.serialization.Serdes$StringSerde
    materializedAs: my-store

在具有@EnableBinding注释的类的主应用程序内部以及@StreamListener注释的方法的内部,我使用的是kafka流DSL和Processor API集成来访问状态存储,由于在应用程序启动时该状态存储应存在,因此application.yml文件。

ReadOnlyKeyValueStore<Object, String> store;

 input.process(() -> new Processor<Object, Product>() {

                @Override
                public void init(ProcessorContext processorContext) {
                    store = (ReadOnlyKeyValueStore) processorContext.getStateStore("my-store");


                }

                @Override
                public void process(Object key, Object value) {
                    //find the key
                    store.get(key);
                }

                @Override
                public void close() {
                    if (state != null) {
                        state.close();
                    }
                }
            }, "my-store");

问题是,在应用程序首次启动时,状态存储尚未完全填充且尚未准备就绪(例如,空的状态存储),但是消息仍较早到达并由Kafka流拓扑处理意外的结果。

我们如何确保在首次启动应用程序时,已完全填充并已准备好在application.yml文件中指示使用物化的所有或特定(用户可以定义)状态存储(在可能的情况下,用户可以定义) @StreamListener中定义的任何流处理拓扑都开始处理传入消息。我们是否可以强制消息的流处理等待,直到首次启动应用程序时状态存储已完全填充?

我试图通过修改spring-cloud-stream sample之一来复制该问题,然后推送修改后的版本herehere

对此也有更详细的讨论。

1 个答案:

答案 0 :(得分:0)

似乎您需要使用GlobalKTable(状态存储)加入流,而不是使用流程接口。这是Kstream join GlobalKTable。请尝试一下。