[英]Binding GlobalStateStore into Processor with spring-cloud-stream-binder-kafka
Initial Question: I have a question how I can bind my GlobalStateStore to a processor.初始问题:我有一个问题,如何将我的 GlobalStateStore 绑定到处理器。 My Application has a GlobalStateStore with an own processor ("GlobalConfigProcessor") to keep the Store up to date.我的应用程序有一个 GlobalStateStore 和一个自己的处理器(“GlobalConfigProcessor”)来保持商店最新。 Also, I have another Processor ("MyClassProcessor") which is called in my Consumer Function. Now I try to access the store from MyClassProcessor, but I get an exception saying: Invalid topology: StateStore config_statestore is not added yet.此外,我还有另一个处理器(“MyClassProcessor”),它在我的消费者 Function 中调用。现在我尝试从 MyClassProcessor 访问商店,但我收到一个异常消息:拓扑无效:StateStore config_statestore 尚未添加。
Update on current situation: I setup a test repository to give a better overview over my situation.当前情况更新:我设置了一个测试存储库,以便更好地了解我的情况。 This can be found here: https://github.com/fx42/store-example这可以在这里找到: https://github.com/fx42/store-example
As you can see in the repo, I have two Consumers which both consume different topics.正如您在回购协议中看到的那样,我有两个消费者,它们都使用不同的主题。 The Config-Topic provides an event which I want to write to a GlobalStateStore. Config-Topic 提供了一个我想写入 GlobalStateStore 的事件。 Here are the StateStoreUpdateConsumer.java and the StateStoreProcessor.java involved.这里涉及到StateStoreUpdateConsumer.java和StateStoreProcessor.java。 With the MyClassEventConsumer.java I process another Input-Topic and want to read values from the GlobalStateStore.使用 MyClassEventConsumer.java,我处理另一个输入主题并希望从 GlobalStateStore 中读取值。 As provided in this doc I can't initialize GlobalStateStores just as StateStoreBean but instead I have to add this actively with the StreamsBuilderFactoryBeanCustomizer Bean.如本文档中所提供的,我无法像初始化 StateStoreBean 一样初始化 GlobalStateStores,而是必须使用 StreamsBuilderFactoryBeanCustomizer Bean 主动添加它。 This Code is currently commented out in the StreamConfig.java.此代码目前在 StreamConfig.java 中已被注释掉。 Without this code I get the Exception没有这段代码我得到异常
org.springframework.kafka.KafkaException: Could not start stream: ; nested exception is org.apache.kafka.streams.errors.TopologyException: Invalid topology: Topology has no stream threads and no global threads, must subscribe to at least one source topic or global table.
If the code is in use I get the exception:如果代码正在使用中,我会得到异常:
org.springframework.kafka.KafkaException: Could not start stream: ; nested exception is org.apache.kafka.streams.errors.StreamsException: Unable to initialize state, this can happen if multiple instances of Kafka Streams are running in the same state directory
So this leads my to the decision, that I have a configuration problem so the topology is messed up.所以这导致我的决定,我有一个配置问题,所以拓扑被搞砸了。
Questions:问题:
streamBuilder.addGlobalStore(storeBuilder, configInputTopic,
Consumed.with(Serdes.String(), Serdes.String()), () -> new StateStoreProcessor(statestoreName));
do I have to provide a Consumer Function for this Processor or do I even have to mention it in the function configuration/application.yml?我必须为此处理器提供消费者 Function 还是我什至必须在 function configuration/application.yml 中提及它?
Is there a way NOT to provide a ProcessorSupplier into the addGlobalStore
call and just use the functional way for this?有没有办法addGlobalStore
调用中提供 ProcessorSupplier 而只使用功能方式?
How can I handle this GlobalStateStore if there are two different topologies for both the defined functions?如果两个定义的函数有两种不同的拓扑结构,我该如何处理这个 GlobalStateStore?
Here is the commented out StreamBuilderFactoryCustomizer Bean which I use to add the GlobalStateStore to the FactoryBean:这是注释掉的 StreamBuilderFactoryCustomizer Bean,我用它来将 GlobalStateStore 添加到 FactoryBean:
@Bean
StreamsBuilderFactoryBeanCustomizer streamsBuilderFactoryBeanCustomizer(
StoreBuilder<KeyValueStore<String, String>> storeBuilder) {
return factoryBean -> {
try {
var streamBuilder = factoryBean.getObject();
streamBuilder.addGlobalStore(storeBuilder, configInputTopic,
Consumed.with(Serdes.String(), Serdes.String()), () -> new StateStoreProcessor(statestoreName));
} catch (Exception e) {
e.printStackTrace();
}
};
} };
}
I figured out my problem.我想通了我的问题。 For me it was the @EnableKafkaStreams annotation which I used.对我来说,这是我使用的@EnableKafkaStreams 注释。 I assume this was the reason I had two different contexts running in parallel and they collided.我认为这就是我有两个不同的上下文并行运行并且它们发生冲突的原因。 Also I needed to use the StreamsBuilderFactoryBeanConfigurer
instead of StreamsBuilderFactoryBeanCustomizer
to get the GlobalStateStore registered correctly.此外,我需要使用StreamsBuilderFactoryBeanConfigurer
而不是StreamsBuilderFactoryBeanCustomizer
来正确注册 GlobalStateStore。 Theses changes done in the linked test-repo which now can start the Application Context properly.这些更改在链接的测试库中完成,现在可以正确启动应用程序上下文。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.