无法仅运行此简单流,...需要SERDE配置吗?

时间:2018-07-21 09:58:43

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

是的,我已经阅读了所有找到的文档,并尝试了有关配置的所有替代方法,但是仅此简单的示例(该行应该记录一行)不起作用

(这是一个带有spring-cloud-stream-binder-kafka-streams的Spring-Boot-2应用程序)

Kafka正在存储一个字符串值(空键)

我的aplilication.yaml

spring:
  cloud:
    stream:
      bindings:
        input:
          destination: 'myStreamTopic'
    output:
          producer.keySerde: 'org.apache.kafka.common.serialization.Serdes$StringSerde'
      kafka:
        streams:
          binder:
            configuration:
              default.key.serde: 'org.apache.kafka.common.serialization.Serdes$StringSerde'
              default.value.serde: 'org.apache.kafka.common.serialization.Serdes$StringSerde'
            brokers:
              - 'ommited:9092'
              - 'ommited:9092'
              - 'ommited:9092'
            application-id: hack1

将此简单代码作为POC:

@SpringBootApplication
@Slf4j
public class HackatonApplication {

    public static void main(String[] args) {
SpringApplication.run(HackatonApplication.class, args);
}

  @EnableBinding(KafkaStreamsProcessor.class)
  public static class LineProcessor {

    @StreamListener(Sink.INPUT)
    public void process(KStream<?, String> line) {
      log.info("Received: {}", line);
    }

  }

我无法使其运行!

org.springframework.context.ApplicationContextException:无法启动bean'outputBindingLifecycle';嵌套异常是java.lang.IllegalArgumentException:尝试调用公共抽象org.apache.kafka.streams.kstream.KStream org.apache.kafka.streams.kstream.KStream.map(org.apache.kafka.streams.kstream.KeyValueMapper ),但尚未设置任何代表。     在org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:184)〜[spring-context-5.0.7.RELEASE.jar!/:5.0.7.RELEASE]     在org.springframework.context.support.DefaultLifecycleProcessor.access $ 200(DefaultLifecycleProcessor.java:52)〜[spring-context-5.0.7.RELEASE.jar!/:5.0.7.RELEASE]     

对不起,如果这很琐碎,但我已经花了几个小时进行搜索,谷歌搜索并试图找到有案可稽的解决方案。

1 个答案:

答案 0 :(得分:5)

您正在使用开箱即用的KafkaStreamsProcessor进行绑定,该绑定期望一个KStream作为输入,另一个KStream作为输出。如果使用此标准,则必须为输出绑定(例如目标等)提供适当的配置。然后,您的方法必须返回KStream,并且需要在弹簧侧使用SendTo批注进行绑定。如下所示:

@StreamListener(Sink.INPUT)
@SendTo("output")
public KStream<?,String> process(KStream<?, String> line) {
    log.info("Received: {}", line);
    return line;
}

但是,在您的情况下,您可以使用自定义处理器并将其用于EnableBinding

interface CustomKafkaStreamsProcessor {
        @Input("input")
        KStream<?, ?> input();
    } 

,然后将其与绑定一起使用。 @EnableBinding(CustomKafkaStreamsProcessor.class)

那样,您不必更改返回值的方法。