我有一个使Http调用到外部服务的actor。有时服务会使用Http 404进行响应,并且有时也会出现http连接错误。再次重试时,这些都会消失。重试来自Akka Actor的http调用的正确方法是什么
什么是由演员重试请求的最佳方式。
什么,我能想到的是
使用主管战略和重启演员
使用在重试HTTP调用演员递归方法, 最大重试次数次
哪一个是正确的方法,1或2.我认为方法1对于像重试一个Http调用那样简单的事情来说是过度的。请分享你的建议。
我有一个使Http调用到外部服务的actor。有时服务会使用Http 404进行响应,并且有时也会出现http连接错误。再次重试时,这些都会消失。重试来自Akka Actor的http调用的正确方法是什么
什么是由演员重试请求的最佳方式。
什么,我能想到的是
使用主管战略和重启演员
使用在重试HTTP调用演员递归方法, 最大重试次数次
哪一个是正确的方法,1或2.我认为方法1对于像重试一个Http调用那样简单的事情来说是过度的。请分享你的建议。
在我看来,你的两种方法都是有效的。
第一种方法是在我的眼睛拥抱失败,让演员只能做它应该做的(而不是让它处理重试等)
有方面要做到这一点更被动的方式一个整洁的东西建在Akka监督:BackoffSupervisor
在我看来,这是一个完美的适合问题,其中演员由于外部因素失败,它可能是有道理的等待一段时间再试一次(如在你的情况与http调用)。
从文档:
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
))
您可以定义一个最小和最大的补偿和监管当局尝试,直到达到最大重启演员之前两倍的等待时间。只有这样它才会停止尝试。
如果你喜欢你的第二个选择,我不会用递归方法去,但会schedule a message到演员本身在一段时间后再次尝试HTTP调用:
system.scheduler.scheduleOnce(1 seconds, self, TryAgain)
我倒是建议使用“之后”模式。这可以让你在失败的情况下重复你的请求。类似这样的:
def retryRequest(ref: ActorRef, attemptsNumber: Int, step: Int)(
implicit ac: ActorSystem): Future[HttpResponse] = {
implicit val timeout = Timeout(5 seconds)
implicit val ec = ac.dispatcher
val s1 = after[HttpResponse](5 seconds, ac.scheduler) {
Http().singleRequest(HttpRequest(uri = "http://akka.io"))
}
s1 flatMap { res =>
res match {
case HttpResponse(StatusCodes.NotFound, headers, entity, _) => {
if(step < attemptsNumber)
retryRequest(ref, attemptsNumber, (step + 1))
else
s1
}
case HttpResponse(StatusCodes.OK, headers, entity, _) => s1
}
}
}
这也是一个不错的选择 –
感谢您的建议 –