Question

J'ai une application Scala en utilisant Akka qui reçoit des requêtes REST, fait quelques opérations contre une base de données, et répond avec quelques informations au client. Comme il est, mes opérations db prennent beaucoup de temps et mon acteur REST compatible est incapable de répondre à de nouvelles demandes dans l'intervalle, même si je pouvais courir beaucoup d'opérations en même temps contre la DB. J'utilise les annotations de javax.ws.rs à REST permettent les méthodes de mon acteur.

La question; quelle est la meilleure façon de permettre à ma demande de traiter un grand nombre de requêtes simultanées?

EDIT :. Je vais ajouter quelques exemples de code

  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 : Voici ce que je reçois dans le journal. J'envoie les trois demandes de mon navigateur aussi vite que je peux passer d'un onglet et appuyez sur F5, mais le haricot RS attend toujours la première demande de terminer avant de manipuler l'autre.

[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
Était-ce utile?

La solution

Alors que je réalise que ce fil est 4 + mois rassis maintenant, il est intéressant de noter que Akka a une nouvelle implémentation du module HTTP qui transfère la demande en un acteur efficace. Cette approche tire parti de l'API Servlet asynchrone (fonctionne également avec continuations Jetty) pour permettre la demande suspendue à passer à travers le système comme un message et repris à tout moment; en éliminant, par exemple, la nécessité d'utiliser !! pour déclencher le travail d'acteur et de répondre dans le POJO annotée. De même, étant donné que la demande est suspendue dans le récipient, et le contexte est basculée en un acteur aussi vite que possible, il n'y a pas de blocage des fils pour gérer la réponse ou future.

Une façon naïve l'exemple ci-dessus peut être réécrite aujourd'hui:

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")
   }
}

Plus de documentation sont disponibles sur le site akka: http://doc.akkasource.org/http

Autres conseils

vous semblez être en utilisant une ancienne version de Akka.

Je recommande de passer à 0,10 (qui sépare les acteurs et les RS-haricots), vous pouvez utiliser LoadBalancer 1 (et 2 ) pour étrangler la charge de travail, ou de profiter de la WorkStealingDispatcher 3 (et 4 )

Est-ce que l'aide?

Une fois que vous recevez une demande, vous devez créer un nouvel acteur pour gérer cette demande. Passez à l'expéditeur d'origine si l'acteur nouvellement créé qui sait répondre à.

Bien que ce fil est vieux, je voudrais ajouter au mélange Spiffy (bouchon!):

https://github.com/mardambey/spiffy

Qu'est-ce que Spiffy?

Spiffy ...

  • est écrit en Scala
  • utilise la bibliothèque fantastique et acteurs Akka à l'échelle
  • utilise l'API Servlet 3.0 pour le traitement des requêtes asynchrones
  • est modulaire (remplacement des composants est simple)
  • utilise DSLs pour réduire le code où vous ne voulez pas
  • supports des demandes de crochets autour de contrôleurs

Spiffy est un framework web en utilisant Scala, Akka (une mise en œuvre de l'acteur Scala), et l'API Java Servelet 3.0. Il utilise l'interface async et vise à fournir un environnement massivement parallèle et évolutive pour les applications web. divers composants de Spiffy sont tous basés sur l'idée qu'ils doivent être des modules indépendants qui font minimalistes de petites quantités de travail très rapidement et main de la demande à la composante suivante dans le pipeline. Après le dernier composant est effectué le traitement de la demande, il signale le conteneur de servlet par « remplir » la demande et l'envoyer au client.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top