Scala-超时重试HTTP请求

时间:2019-01-25 05:34:48

标签: scala http request retry-logic

我希望创建一个服务,在该服务中它向特定URL发出HTTP请求,如果在1秒钟内未得到结果,则该请求将超时,然后将重试另一个请求,最多3次重试。

如何在scala中实施此操作?

我正在查看Akka HTTP和Play的WSClient的文档,但找不到任何地方提及它。

注意:如果请求在服务器上产生副作用,那么我希望失败的请求不会产生任何副作用。如何实现这种行为?甚至有可能吗?

2 个答案:

答案 0 :(得分:1)

据我所知,您需要做的是:

步骤

  • 通过HTTP调用访问某些API的端点。
  • 如果响应没有在1秒钟之内到来,则需要获取异常。
  • 如果出现异常,则需要重新启动服务,然后再次发送请求。

您可以与Akka Http和Akka Actors合作进行此操作。

使用Akka actor,您可以告诉服务在获取TimeoutException时需要做什么。您可以通过Akka Ask模式进行API调用。 如果您会看到Akka的文档格式,请询问模式here。它需要Akka询问超时,您可以将其设置为所需的任何值,以防万一您没有在超时中返回响应时,将获得AkkaAskTimeOutException,它将由您的子actor捕获,然后将其传递给主管actor ,当Supervisor actor捕获异常时,我们可以使用supervison策略并可以指定需要执行的操作,例如重新启动,关闭,恢复等。

监督策略:您可以here了解它。实际上,以下是基于akka actor的应用程序的基本结构。

Supervisor Actor(我们在主管中编写监督策略),并且有子级演员。

child1(业务逻辑)child2(业务逻辑)

答案 1 :(得分:0)

您也可以从akka模式中使用retry

import akka.pattern.{ask, pipe, retry}
import akka.actor.{Actor, ActorSystem, Props, Scheduler}
import akka.util.Timeout
import scala.concurrent.duration._
import scala.concurrent.{Await, ExecutionContext, Future}

class ClientActor extends Actor { //actor which times out 2 times and succeeds 3rd time

    var attempts = 0

    def receive = {
      case "request" =>
        this.attempts = attempts + 1
        if (attempts < 3) {
          Thread.sleep(2000)
          Future.failed(new Exception("timed out")) pipeTo sender
        } else {
          Thread.sleep(500)
          Future.successful(s"Successful in $attempts attempt") pipeTo sender
        }
        println(s"Attempt: $attempts")
    }
}


val system = ActorSystem("system") //actor system and needed implicits
implicit val ec: ExecutionContext = system.dispatcher 
implicit val timeout: Timeout = Timeout(1 seconds)
implicit val scheduler: Scheduler = system.scheduler


val client = system.actorOf(Props[ClientActor], "client-actor")

val future = retry(() => client ? "request", 3, 1 second) //create future which would retry 3 times

println(Await.result(future, 10 seconds)) //Would write "Successful in 3 attempt"