如何从程序中停止flink流式传输作业

时间:2017-06-08 16:31:30

标签: junit apache-kafka apache-flink flink-streaming

我正在尝试为Flink流作业创建一个JUnit测试,该作业将数据写入kafka主题并分别使用FlinkKafkaProducer09FlinkKafkaConsumer09从同一kafka主题读取数据。我正在传递产品中的测试数据:

DataStream<String> stream = env.fromElements("tom", "jerry", "bill");

并检查相同数据是否来自消费者:

List<String> expected = Arrays.asList("tom", "jerry", "bill");
List<String> result =  resultSink.getResult();
assertEquals(expected, result);

使用TestListResultSink

我可以通过打印流来查看来自消费者的数据。但无法获得Junit测试结果,因为消费者即使在消息完成后也会继续运行。所以它没有来测试部分。

FlinkFlinkKafkaConsumer09中是否可以以任何方式停止流程或运行特定时间?

4 个答案:

答案 0 :(得分:5)

潜在的问题是流媒体程序通常不是有限的并且无限期地运行。

至少在目前,最好的方法是在流中插入一条特殊的控制消息,让源正确终止(只需通过离开读取循环停止读取更多数据)。这样Flink就会告诉所有下游运营商,他们可以在消耗完所有数据后停止运营。

或者,您可以在源中引发特殊异常(例如,在一段时间之后),以便您可以区分“正确”终止与故障情况(通过检查错误原因)。在源代码中抛出异常将使程序失败。

答案 1 :(得分:0)

关注@TillRohrman

如果使用EmbeddedKafka实例,可以组合特殊异常方法并在单元测试中处理它,然后读取EmbeddedKafka主题并断言消费者值。

我发现https://github.com/asmaier/mini-kafka/blob/master/src/test/java/de/am/KafkaProducerIT.java在这方面非常有用。

唯一的问题是您将丢失触发异常的元素,但您始终可以调整测试数据以解决此问题。

答案 2 :(得分:0)

您是否可以在反序列化器中使用isEndOfStream覆盖来停止从Kafka获取?如果我读得正确,flink / Kafka09Fetcher在其run方法中有以下代码,它会破坏事件循环

    if (deserializer.isEndOfStream(value)) {
                        // end of stream signaled
                        running = false;
                        break;
                    }

我的想法是使用Till Rohrmann关于控制消息的想法与这个isEndOfStream方法一起告诉KafkaConsumer停止阅读。

任何不起作用的理由?或者也许是我忽略的一些角落?

https://github.com/apache/flink/blob/07de86559d64f375d4a2df46d320fc0f5791b562/flink-connectors/flink-connector-kafka-0.9/src/main/java/org/apache/flink/streaming/connectors/kafka/internal/Kafka09Fetcher.java#L146

答案 3 :(得分:0)

在测试中,您可以在单独的线程中开始执行作业,等待一段时间以允许它进行数据处理,取消线程(它将中断作业)并进行攻击。

CompletableFuture<Void> handle = CompletableFuture.runAsync(() -> {
    try {
        environment.execute(jobName);
    } catch (Exception e) {
        e.printStackTrace();
    }
});
try {
    handle.get(seconds, TimeUnit.SECONDS);
} catch (TimeoutException e) {
    handle.cancel(true); // this will interrupt the job execution thread, cancel and close the job
}

// Make assertions here