2016-12-21 99 views
2

我嘗試在Scala上實現AKKA http和一些演員。 我用akka創建了一個web應用程序。 但我有一個或2個不同的路線/ 16這個錯誤。 (它顯然是隨機的):akka http與演員:錯誤503超時

服務器無法及時響應您的請求。 請稍後再試!

您能向我解釋爲什麼以及如何解決? 我真的是阿卡的新手。

主類:

object WebServer extends App { 

    implicit val system = ActorSystem("app-1") 
    implicit val materializer = ActorMaterializer() 
    // needed for the future flatMap/onComplete in the end 
    implicit val executionContext = system.dispatcher 
    val routes = SessionRoute.route 
    val bindingFuture = Http().bindAndHandle(routes, ipServer, configApplication.getInt("spray.can.client.proxy.http.port")) 
    println("serv http launch") 
    StdIn.readLine 
    bindingFuture 
     .flatMap(_.unbind()) // trigger unbinding from the port 
     .onComplete(_ => { 
     cluster.close() 
     system.terminate() 
    }) 
    bindingFuture.onFailure { 
     case ex: Exception => 
      println(ex, "Failed to bind to {}:{}!", ipServer, configApplication.getInt("spray.can.client.proxy.http.port")) 
    } 
    } 

我的路線是:

object SessionRoute extends TokenValidator { 
implicit val formats = org.json4s.DefaultFormats 

val sessionHandler = WebServer.system.actorOf(SessionHandler.props(), "SessionHandler") 
implicit val timeout = Timeout(60.seconds) 


val route: Route = get { 
    authenticated(doAuthPublisher) { app => 
     getActiveUserPublisher 
    } 
} 
def getActiveUserPublisher = 
    path("session"/JavaUUID/"active_user") { publisher_id => 
     parameters('date_start.as[Long], 'date_end.as[Long]) { 
      (date_start, date_end) => { 
       onSuccess(sessionHandler ? SessionActiveUser(SessionRequest(publisher_id, date_start, date_end, null))) { 
        case response: Answer => 
         complete(StatusCodes.OK, response.result) 
        case _ => 
         complete(StatusCodes.InternalServerError, "Error on the page") 
       } 
      } 
     } 

    } 
} 

我的演員是:使用

object SessionHandler { 
     def props(): Props = { 
      Props(classOf[SessionHandler]) 
     } 
    } 
    class SessionService(implicit actorSystem: ActorSystem) extends toolService { 
    def activeUser(sessionRequest: SessionRequest): Map[String, Any] = { 
    .... 
     } 
    } 

class SessionHandler extends Actor with ActorLogging { 
    implicit val system = ActorSystem("session") 
    implicit val formats = org.json4s.DefaultFormats 

    def receive: Receive = { 
    case request: SessionActiveUser => 
    sender() ! Answer(Serialization.write(new SessionService().activeUser(request.sessionRequest))) 
    }} 

而我的情況下類:

final case class Answer(result: String) 
case class SessionActiveUser(sessionRequest: SessionRequest) 
case class SessionRequest(publisher_id: UUID = null, date_start: Long, date_end: Long, app_id: String = null) 

我configuration.conf:

akka { 
    loglevel = INFO 
    stdout-loglevel = INFO 
    loggers = ["akka.event.slf4j.Slf4jLogger"] 
    default-dispatcher { 
    fork-join-executor { 
     parallelism-min = 8 
    } 
    } 
// event-handlers = ["akka.event.slf4j.Slf4jLogger"] 
} 

回答

1

您所看到的錯誤是造成你的route不能夠產生配置的請求超時時間內響應。如果您沒有明確設置它,則默認爲20秒。有關請求超時的更多信息,請參見here

關於發生這種情況的原因,您可以詳細瞭解activeUser函數中會發生什麼嗎?在那裏發生任何重大阻塞?如果是這樣,所有傳入的請求將被順序化並阻止activeUser,最終導致請求超時來終止您的請求。

可能的解決方案是:

  • 讓你的服務異步/無阻塞
  • 按照有關如何處理阻塞阿卡-HTTP路線內來電docs