简体   繁体   English

具有退避和重试限制的Actor重试

[英]Actor retry with back-off and retry limit

I need retry mechanism on akka actors with increasing time between the retries and maximum retry limit. 我需要在Akka演员上使用重试机制,以增加重试之间的时间和最大重试限制。 For this purpose I'm trying to use the BackOffSupervisor pattern, provided by akka. 为此,我尝试使用akka提供的BackOffSupervisor模式。 The problem is that, from my test, the back-off strategy and the retry limit seems to not work. 问题是,根据我的测试,退避策略和重试限制似乎不起作用。 Or maybe the problem is in the test? 也许问题出在测试中?

The test looks like this: 测试如下所示:

A simple actor that throws exception at the first 5 messages 一个简单的actor,在前5条消息中引发异常

class SomeActor extends AbstractActor {

private static int messageCounter = 0;

//return the message to sender
@Override
public void preRestart(final Throwable reason, final Optional<Object> message) {
    getSelf().tell(message.get(), getSender());
}


@Override
public Receive createReceive() {
    return receiveBuilder()
            .matchEquals("hello", message -> {
                messageCounter++;
                getSender().tell("response", getSelf());

                //Throw Exception at the first 5 messages
                if (messageCounter < 5) {
                    throw new Exception();
                }

            })
            .build();
}

} }

The BackOffSupervisor configuration BackOffSupervisor配置

private ActorRef createSupervisedActor(Class<? extends Actor> actorClass) {
    final Props someActorProps = Props.create(actorClass);

    final Props supervisorProps = BackoffSupervisor.props(
            Backoff.onStop(
                    someActorProps, //actor to be supervised
                    "someActor",
                    Duration.ofSeconds(10), //min back-off time
                    Duration.ofMinutes(2), // max back-off time
                    0.2, // back-off increase factor
                    10) // max retry limit
                    .withSupervisorStrategy(
                            new OneForOneStrategy(
                                    DeciderBuilder
                                            .match(Exception.class, e -> SupervisorStrategy.restart())
                                            .matchAny(o -> SupervisorStrategy.escalate())
                                            .build())
                    )
    );

    return testSystem.actorOf(supervisorProps);

}

And the test method 和测试方法

    @Test
public void test() {
    new TestKit(testSystem) {{
        ActorRef actorRef = createSupervisedActor(SomeActor.class);

        actorRef.tell("hello", getRef());

        //Expect 5 responses in 1 second
        receiveN(5, Duration.ofSeconds(1));
    }};

}

The test finishes way too fast. 测试完成得太快。 In under a second, when from the configuration of the BackoffSupervisor, I'm expecting to take at least a 50+ sec. 在不到一秒钟的时间内,从BackoffSupervisor的配置中,我预计至少需要50秒钟以上的时间。

The problem was due to the following reason: 该问题是由于以下原因引起的:

Throwing an exception in the child actor(someActor in my case) is not handled by Backoff.onStop and therefore handled by normal default supervision, which means immediate restart. Backoff.onStop不处理在子actor(在我的情况下为someActor)中引发异常,因此由正常的默认监督处理,这意味着立即重启。 - https://github.com/akka/akka/issues/23406#issuecomment-372602568 -https://github.com/akka/akka/issues/23406#issuecomment-372602568

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

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