Подтвердить что ты не робот

Как масштабировать приложение Scala REST, использующее Akka?

У меня есть приложение Scala, использующее Akka, которое получает запросы REST, выполняет некоторые операции с базой данных и отвечает некоторой информацией клиенту. Как бы то ни было, мои операции с db занимают много времени, и мой агент с включенным REST не может отвечать на новые запросы тем временем, хотя я мог бы запускать много операций одновременно с БД. Я использую аннотации javax.ws.rs для методов REST-enable в моем акторе.

Вопрос; как лучше всего включить мое приложение для обработки большого количества одновременных запросов?

EDIT. Я добавлю несколько примеров кода.

  import se.scalablesolutions.akka.actor._
  import javax.ws.rs._

  @Path("/test")
  class TestService {

    @GET
    def status() = 
      actorPool !! Status(session).
        getOrElse(<error>Unable to connect to service</error>)
  }

  class TestActor {

    def receive = {
      case Status() => {
        reply(SomeObject.slowDBMethod)
      }
    }
  }

  case class Status()

EDIT2: Это то, что я получаю в журнале. Я отправляю три запроса из своего браузера так быстро, как только могу переключаться на вкладки и нажимать F5, но RS bean все еще ждет завершения первого запроса, прежде чем обращаться с ним.

[INFO] [2010-08-29 16:27:03,232] [akka:event-driven:dispatcher:global-15] c.n.StatusActor: got Slow request
[INFO] [2010-08-29 16:27:06,916] [akka:event-driven:dispatcher:global-10] c.n.StatusActor: got Slow request
[INFO] [2010-08-29 16:27:10,589] [akka:event-driven:dispatcher:global-3] c.n.StatusActor: got Slow request
4b9b3361

Ответ 1

В то время как я понимаю, что этот поток застыл в 4 месяца, стоит отметить, что Akka имеет новую реализацию HTTP-модуля, которая эффективно передает запрос в актера. Этот подход использует асинхронный API сервлета (также работает с продолжением Jetty), чтобы позволить приостановленному запросу проходить через систему в виде сообщения и возобновляться в любой точке; исключая, например, необходимость использования! для запуска работы актера и ответа в аннотированном POJO. Аналогично, поскольку запрос приостанавливается в контейнере, и контекст превращается в актера как можно быстрее, нет никаких потоков, блокирующих обработку ответа или будущего.

Один наивный способ, описанный выше, может быть переписан сегодня:

class TestEndpoint extends Actor with Endpoint {
   def hook(uri:String) = uri == "/test"
   def provide(uri:String) = actorOf[TestService].start

   override def preStart = {
     ActorRegister.actorsFor[classOf[RootEndpoint]).head ! Endpoint.Attach(hook, provide)
   }

   def receive = handleHttpRequest
}

class TestService extends Actor {
   def receive = {

     case get:Get => 
       get.timeout(SomeObject.TimeoutInSeconds) // for example
       get.OK(SomeObject.slowDBMethod)

     case other:RequestMethod =>
      other.NotAllowed("Invalid method for this endpoint")
   }
}

Дополнительную документацию можно найти на сайте akka: http://doc.akkasource.org/http

Ответ 2

вы, кажется, используете более старую версию Akka.

Я рекомендую обновить до 0.10 (который разделяет Actors и RS- Beans), тогда вы можете использовать LoadBalancer 12), чтобы дросселировать рабочую нагрузку или использовать WorkStealingDispatcher 34)

Помогает ли это?

Ответ 3

Как только вы получите запрос, вы должны создать нового актера для обработки этого запроса. Передайте оригинальному отправителю, чтобы вновь созданный актер знал, на кого ответить.

Ответ 4

Хотя этот поток старый, я хотел бы добавить Spiffy (plug!) в микс:

https://github.com/mardambey/spiffy

Что такое Spiffy?

Spiffy...

  • записывается в Scala
  • использует фантастическую библиотеку Akka и актеров для масштабирования.
  • использует сервлет API 3.0 для обработки асинхронных запросов
  • является модульным (замена компонентов осуществляется прямо).
  • использует DSL для сокращения кода, где вы этого не хотите.
  • поддерживает запросы на крючки вокруг контроллеров.

Spiffy - это веб-фреймворк с использованием Scala, Akka (a Scala actor) и API Java Servelet 3.0. Он использует асинхронный интерфейс и нацелен на создание широкомасштабной параллельной и масштабируемой среды для веб-приложений. Всевозможные компоненты Spiffy основаны на идее, что они должны быть независимыми минималистическими модулями, которые очень быстро выполняют небольшую работу и передают запрос следующему компоненту в конвейере. После того как последний компонент обработает запрос, он сигнализирует контейнер сервлета путем "завершения" запроса и отправки его клиенту.