2016-12-21 4 views
2

Я пытаюсь реализовать AKKA http и некоторые актеры на Scala. Я создал веб-приложение с аккой. Но у меня есть эта ошибка на одном или двух разных маршрутах/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, что в конечном итоге приведет к таймаутам запроса, чтобы убить ваши запросы.

Возможные решения:

  • сделать свой сервис асинхронной/неблокирующая
  • следовать docs о том, как иметь дело с блокировкой вызовов внутри Akka-HTTP маршрутов