简体   繁体   English

Akka流onFailuresWithBackoff不会重新启动流

[英]Akka Streams onFailuresWithBackoff not restarting flow

I'm attempting to use RestartFlow in Akka Streams javadsl to restart one of my flow stages if any failures occur during the stage, but it doesn't seem to be restarting the flow and instead just drops the message. 我正在尝试在Akka Streams javadsl中使用RestartFlow重新启动流阶段之一,如果该阶段发生任何故障,但是它似乎并没有重新启动流,而是只是丢弃了消息。

I've already seen this: RestartFlow in Akka Streams not working as expected , but I'm on version 2.5.19 so it should be fixed? 我已经看到了这一点: Akka Streams中的RestartFlow不能按预期工作 ,但是我使用的版本是2.5.19,因此应该对其进行修复吗?

I've tried both RestartFlow.onFailuresWithBackoff and RestartFlow.withBackoff but neither of those worked. 我已经尝试了RestartFlow.onFailuresWithBackoffRestartFlow.withBackoff但都没有用。 I've also tried playing with the overall Actor system supervisor strategy, but that seems to just intercept the exception so that it isn't thrown from the flow and plus doesn't seem to offer the backoff and max retry strategy that I want. 我也尝试过使用整个Actor系统主管策略,但这似乎只是拦截异常,这样它就不会从流程中抛出,而且似乎也没有提供我想要的退避和最大重试策略。

The stream: 流:

public Consumer.DrainingControl<Done> stream() {
    return Consumer.committableSource(consumerSettings,
        Subscriptions.topics(config.getString(ConfigKeys.KAFKA_CONFIG_PREFIX +
            ConfigKeys.CONSUMER_TOPIC)))
        .via(RestartFlow.onFailuresWithBackoff(
                Duration.ofSeconds(1), // min backoff
                Duration.ofSeconds(2), // max backoff,
                0.2, // adds 20% "noise" to vary the intervals slightly
                10, // limits the amount of restarts to 10
                this::dispatchMessageFlow))
        .via(Committer.flow(CommitterSettings.create(system)))
        .toMat(Sink.ignore(), Keep.both())
        .mapMaterializedValue(Consumer::createDrainingControl)
        .run(mat);
}

And then the flow: 然后流程:

private Flow<ConsumerMessage.CommittableMessage<String, String>,
    ConsumerMessage.Committable, NotUsed> dispatchMessageFlow() {
    return Flow.<ConsumerMessage.CommittableMessage<String, String>>create()
            .mapAsyncUnordered(
                config.getInt(ConfigKeys.PARALLELISM),
                msg ->
                    streamProcessor.process(msg.record().value())
                        .whenComplete((done, e) -> {
                            if (e != null) {
                                throw new RuntimeException(e);
                            } else {
                                if (done.status().isSuccess()){
                                    streamingConsumerLogger.info("Successfully posted message, got response:\n{}",
                                        done.toString());
                                } else {
                                    throw new RuntimeException("HTTP Error!");
                                }
                            }
                        })
                        .thenApply(done -> msg.committableOffset()));
}

I see the exception once, with akka stating that it is going to restart the graph due to failure, but nothing else after that. 我见过一次异常,akka表示由于失败将要重新启动图形,但此后没有其他事情。 According to my understanding I should be seeing it 10 more times. 根据我的理解,我应该再看10次。 The consumer continues to listen to new messages so it seems like the message is just dropped. 消费者继续收听新消息,因此似乎该消息刚刚被丢弃。

java.util.concurrent.CompletionException: java.lang.RuntimeException: HTTP Error!
    at java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:292)
    at java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:308)
    at java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:769)
    at java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:736)
    at java.util.concurrent.CompletableFuture$Completion.exec(CompletableFuture.java:443)
    at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
    at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
    at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
    at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
Caused by: java.lang.RuntimeException: HTTP Error!
    at com.company.app.messageforwarder.StreamingConsumerService.lambda$null$0(StreamingConsumerService.java:72)
    at java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:760)
    ... 6 more

If anyone could please help point me in the right direction I would appreciate it. 如果有人可以帮助我指出正确的方向,我将不胜感激。

it works a bit different way. 它的工作方式有些不同。 long story short - if error happens, the message is dropped, but the source/flow would be just restarted, without killing the whole stream. 长话短说-如果发生错误,则会丢弃该消息,但是将仅重新启动源/流,而不会杀死整个流。 it's described in the RestartFlow.onFailuresWithBackoff documentation : RestartFlow.onFailuresWithBackoff文档中进行了描述:

The restart process is inherently lossy, since there is no coordination between cancelling and the sending of messages. 重新启动过程本质上是有损耗的,因为取消和消息发送之间没有协调。 A termination signal from either end of the wrapped Flow will cause the other end to be terminated, and any in transit messages will be lost. 来自包装流的任一端的终止信号将导致另一端终止,并且任何传输中的消息都将丢失。 During backoff, this Flow will backpressure. 在回退期间,此流量将回压。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM