Akka主管策略-正确的用例 [英] Akka Supervisor Strategy - Correct Use Case
问题描述
我一直在使用Akka Supervisor Strategy来处理业务逻辑异常。
I have been using Akka Supervisor Strategy to handle business logic exceptions.
阅读最著名的Scala博客系列之一新植物 ,我发现他为我一直以来所做的事情提供了不同的目的。
Reading one of the most famous Scala blog series Neophyte, I found him giving a different purpose for what I have always been doing.
例如:
让我们说我有一个HttpActor,应该与外部资源联系,以防万一它掉了,我会抛出一个异常,现在是 ResourceUnavailableException
。
Let's say I have an HttpActor that should contact an external resource and in case it's down, I will throw an Exception, for now a ResourceUnavailableException
.
万一我的Supervisor意识到了这一点,我将在HttpActor上调用Restart,在HttpActor的 preRestart
方法中,我将调用do schedulerOnce
重试一次。
In case my Supervisor catches that, I will call a Restart on my HttpActor, and in my HttpActor preRestart
method, I will call do a schedulerOnce
to retry that.
演员:
class HttpActor extends Actor with ActorLogging {
implicit val system = context.system
override def preRestart(reason: Throwable, message: Option[Any]): Unit = {
log.info(s"Restarting Actor due: ${reason.getCause}")
message foreach { msg =>
context.system.scheduler.scheduleOnce(10.seconds, self, msg)
}
}
def receive = LoggingReceive {
case g: GetRequest =>
doRequest(http.doGet(g), g.httpManager.url, sender())
}
一个主管:
class HttpSupervisor extends Actor with ActorLogging with RouterHelper {
override val supervisorStrategy =
OneForOneStrategy(maxNrOfRetries = 5) {
case _: ResourceUnavailableException => Restart
case _: Exception => Escalate
}
var router = makeRouter[HttpActor](5)
def receive = LoggingReceive {
case g: GetRequest =>
router.route(g, sender())
case Terminated(a) =>
router = router.removeRoutee(a)
val r = context.actorOf(Props[HttpActor])
context watch r
router = router.addRoutee(r)
}
}
这是什么意思?
如果我的 doRequest
方法抛出 ResourceUnavailableException
,主管将获取该信息并重新启动actor ,根据调度程序,迫使它在一段时间后重新发送消息。我看到的优点是我免费获得了重试次数以及处理异常本身的好方法。
In case my doRequest
method throws the ResourceUnavailableException
, the supervisor will get that and restart the actor, forcing it to resend the message after some time, according to the scheduler. The advantages I see is the fact I get for free the number of retries and a nice way to handle the exception itself.
现在看博客,他发现了一个不同的例子。万一您需要重试的方法,只需发送这样的消息即可:
Now looking at the blog, he shows a different approach in case you need a retry stuff, just sending messages like this:
def receive = {
case EspressoRequest =>
val receipt = register ? Transaction(Espresso)
receipt.map((EspressoCup(Filled), _)).recover {
case _: AskTimeoutException => ComebackLater
} pipeTo(sender)
case ClosingTime => context.system.shutdown()
}
如果
,他通过管道将结果作为 Future
的> AskTimeoutException ComebackLater
对象,
Here in case of AskTimeoutException
of the Future
, he pipes the result as a ComebackLater
object, which he will handle doing this:
case ComebackLater =>
log.info("grumble, grumble")
context.system.scheduler.scheduleOnce(300.millis) {
coffeeSource ! EspressoRequest
}
对我来说,您可以使用策略主管来做很多事情,
For me this is pretty much what you can do with the strategy supervisor, but in a manually way, with no built in number of retries logic.
那么这里最好的方法是什么?为什么呢?我使用akka主管策略的概念是完全错误的吗?
So what is the best approach here and why? Is my concept of using akka supervisor strategy completely wrong?
推荐答案
您可以使用 BackoffSupervisor
:
以内置模式提供
akka.pattern.BackoffSupervisor
实施所谓的指数退避监管策略,在子角色失败时重新启动子角色,每次重新启动之间的时间间隔都会越来越长。
Provided as a built-in pattern the
akka.pattern.BackoffSupervisor
implements the so-called exponential backoff supervision strategy, starting a child actor again when it fails, each time with a growing time delay between restarts.
val supervisor = BackoffSupervisor.props(
Backoff.onFailure(
childProps,
childName = "myEcho",
minBackoff = 3.seconds,
maxBackoff = 30.seconds,
randomFactor = 0.2 // adds 20% "noise" to vary the intervals slightly
).withAutoReset(10.seconds) // the child must send BackoffSupervisor.Reset to its parent
.withSupervisorStrategy(
OneForOneStrategy() {
case _: MyException => SupervisorStrategy.Restart
case _ => SupervisorStrategy.Escalate
}))
这篇关于Akka主管策略-正确的用例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!