在Spring云数据流中,Sink组件无法使用kafka获取正确的数据

时间:2016-09-06 09:34:19

标签: spring-integration spring-cloud-stream spring-cloud-dataflow spring-kafka

我不是以英语为母语的人,但我尽量表达我的问题。 我遇到了这个问题,这让我困惑了两天,我仍然无法找到解决方案。

我已经构建了一个将在Hadoop YARN中的Spring Can Data Flow中运行的流。

该流由Http源,处理器和文件接收器组成。

1.Http来源
HTTP Source组件有两个输出通道绑定两个不同的目标,即dest.properties中定义的dest1和dest2。

spring.cloud.stream.bindings.output.destination = DEST1 spring.cloud.stream.bindings.output2.destination = dest2

以下是HTTP源代码snipet供您参考..

@Autowired
    private EssSource channels; //EssSource is the interface for multiple output channels

##output channel 1:
    @RequestMapping(path = "/file", method = POST, consumes = {"text/*", "application/json"})
    @ResponseStatus(HttpStatus.ACCEPTED)
    public void handleRequest(@RequestBody byte[] body, @RequestHeader(HttpHeaders.CONTENT_TYPE) Object contentType) {
        logger.info("enter ... handleRequest1...");
        channels.output().send(MessageBuilder.createMessage(body,
                new MessageHeaders(Collections.singletonMap(MessageHeaders.CONTENT_TYPE, contentType))));
    }

##output channel 2:
    @RequestMapping(path = "/test", method = POST, consumes = {"text/*", "application/json"})
    @ResponseStatus(HttpStatus.ACCEPTED)
    public void handleRequest2(@RequestBody byte[] body, @RequestHeader(HttpHeaders.CONTENT_TYPE) Object contentType) {
        logger.info("enter ... handleRequest2...");
        channels.output2().send(MessageBuilder.createMessage(body,
                new MessageHeaders(Collections.singletonMap(MessageHeaders.CONTENT_TYPE, contentType))));
    }

2。处理器
处理器有两个多输入通道和两个输出通道,用于绑定不同的目的地。    目标绑定在处理器组件项目的application.properties中定义。

//input channel binding  
spring.cloud.stream.bindings.input.destination=dest1
spring.cloud.stream.bindings.input2.destination=dest2

//output channel binding  
spring.cloud.stream.bindings.output.destination=hdfsSink
spring.cloud.stream.bindings.output2.destination=fileSink

以下是处理器的代码段。

@Transformer(inputChannel = EssProcessor.INPUT, outputChannel = EssProcessor.OUTPUT)
    public Object transform(Message<?> message) {
        logger.info("enter ...transform...");

        return "processed by transform1";;
    }


    @Transformer(inputChannel = EssProcessor.INPUT_2, outputChannel = EssProcessor.OUTPUT_2)
    public Object transform2(Message<?> message) {
        logger.info("enter ... transform2...");
        return "processed by transform2";
    }

第3。文件接收器组件。

我使用Spring的官方fil sink组件。    行家://org.springframework.cloud.stream.app:文件灌入卡夫卡:1.0.0.BUILD-SNAPSHOT

我只是在其applicaiton.properties文件中添加目标绑定。    spring.cloud.stream.bindings.input.destination =文件接收

4.Finding:

我期望的数据流应该是这样的:

Source.handleRequest() - &gt; Processor.handleRequest()

Source.handleRequest2() - &gt; Processor.handleRequest2() - &gt; Sink.fileWritingMessageHandler();

只应将“由transform2处理”的字符串保存到文件中。

但在我测试之后,数据流是这样的:

Source.handleRequest() - &gt; Processor.handleRequest() - &gt; Sink.fileWritingMessageHandler();

Source.handleRequest2() - &gt; Processor.handleRequest2() - &gt; Sink.fileWritingMessageHandler();

“由transform1处理”和“由transform2处理”字符串都保存到文件中。

5.Question:

虽然Processor.handleRequest()中输出通道的目标绑定到hdfsSink而不是fileSink,但数据仍然会流向文件Sink。我无法理解这一点,这不是我想要的。   我只希望来自Processor.handleRequest2()的数据流向文件接收器而不是两者。   如果我做得不对,有谁可以告诉我该怎么做以及解决方案是什么?   这让我困惑了2天。

感谢您的帮助。

亚历

1 个答案:

答案 0 :(得分:2)

您的流定义是这样的(其中'-2'版本是具有多个渠道的版本)?

http-source-2 | processor-2 | file-sink

请注意,Spring Cloud数据流将覆盖applications.properties中定义的目标,这就是为什么即使处理器的spring.cloud.stream.bindings.output.destination设置为hdfs-sink,它也会实际匹配输入file-sink

此处解释了从流定义配置目标的方式(在点击的上下文中):http://docs.spring.io/spring-cloud-dataflow/docs/current/reference/htmlsingle/#spring-cloud-dataflow-stream-tap-dsl

您可以做的是简单地交换通道1和2的含义 - 使用侧通道进行hdfs。这有点脆弱 - 因为流的input / output通道将自动配置,而其他通道将通过application.properties进行配置 - 在这种情况下可能更好通过流定义或部署时配置辅助通道目标 - 请参阅http://docs.spring.io/spring-cloud-dataflow/docs/current/reference/htmlsingle/#_application_properties

在我看来,这些也可能是两个流使用常规组件监听单独的端点 - 假设数据应该并排流动。