2010-08-21 6 views
12

Possiedo un'applicazione Scala che utilizza Akka che riceve richieste REST, esegue alcune operazioni su un database e risponde con alcune informazioni al client. Così com'è, le mie operazioni db richiedono molto tempo e il mio attore abilitato a REST non è in grado di rispondere a nuove richieste nel frattempo, anche se potrei eseguire molte operazioni contemporaneamente contro il DB. Sto usando le annotazioni javax.ws.rs sui metodi REST-enable nel mio attore.Come si ridimensiona l'applicazione Scala REST che utilizza Akka?

La domanda; qual è il modo migliore per consentire alla mia applicazione di gestire un numero elevato di richieste simultanee?

MODIFICA: Aggiungerò un po 'di codice di esempio.

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: Questo è quello che sto ottenendo nel registro. Sto inviando le tre richieste dal mio browser tanto velocemente quanto posso cambiare le schede e premere F5, ma il bean RS attende ancora la prima richiesta da completare prima di gestire il successivo.

[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 
+0

Si consiglia di esaminare la panca Apache invece di premere F5 così tanto ottimo strumento per i test di concorrenza. http://httpd.apache.org/docs/2.2/programs/ab.html – cbmeeks

risposta

6

Mentre realizzo questa discussione è 4+ mesi stantio adesso, vale la pena notare che Akka ha una nuova implementazione modulo HTTP che trasferisce la richiesta in un attore efficientemente. Questo approccio sfrutta l'API servlet asincrona (funziona anche con le continuazioni di Jetty) per consentire alla richiesta sospesa di essere passata attraverso il sistema come un messaggio e ripresa in qualsiasi momento; eliminando, per esempio, la necessità di usare !! per attivare il lavoro degli attori e rispondere nel POJO annotato. Allo stesso modo, poiché la richiesta è sospesa nel contenitore e il contesto è capovolto in un attore il più rapidamente possibile, non ci sono thread che bloccano la risposta o il futuro.

Un modo ingenuo l'esempio precedente potrebbe essere riscritta oggi:

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

Ulteriore documentazione può essere trovata sul sito Akka: http://doc.akkasource.org/http

3

Una volta ricevuta una richiesta, è necessario creare un nuovo attore per gestire tale richiesta. Trasmetti il ​​mittente originale in modo che l'attore appena creato sappia a chi rispondere.

+0

In una situazione di attore "normale", mi aspetto che funzioni. Ma nel mio caso non posso davvero passare il "mittente" nel metodo status() del campione di codice aggiunto? Presumo che qualunque cosa faccia nel metodo di ricezione, l'attore non sarà pronto per ulteriori richieste REST finché il metodo status() non è stato completato. – Magnus

+0

Che ne dici di mantenere l'attore per sessione utente? – andreypopp

7

sembra che tu stia utilizzando una versione precedente di Akka.

vi consiglio di passare a 0,10 (che separa Attori e RS-Fagioli), quindi è possibile utilizzare LoadBalancer 1 (e 2) della valvola a farfalla del carico di lavoro, o approfittare del WorkStealingDispatcher 3 (e 4)

Questo aiuto?

+0

Sembra promettente. Proverò 0,10. – Magnus

+0

Non sono riuscito a trovare una versione 0.10 di akka-rest, almeno nel repository di maven2. Dovrei usare la versione 0.8? – Magnus

+0

@Magnus Vedi http://doc.akkasource.org/getting-started#The%20Next%20Steps-Using%20Akka%20with%20Maven –

1

Anche se questa discussione è vecchio, vorrei aggiungere Spiffy (spina!) al mix:

https://github.com/mardambey/spiffy

cosa è Spiffy?

Spiffy ...

  • è scritto in Scala
  • usa la fantastica libreria di Akka e gli attori per scalare
  • utilizza servlet API 3.0 per la gestione asincrona richiesta
  • è modulare (la sostituzione dei componenti è semplice)
  • utilizza DSL per ridurre il codice in cui non si desidera che
  • appoggia la richiesta ganci intorno controllori

Spiffy è un framework web che utilizza Scala, Akka (un'implementazione di attore Scala) e l'API Java Servelet 3.0. Fa uso dell'interfaccia async e mira a fornire un ambiente estremamente parallelo e scalabile per le applicazioni web. I vari componenti di Spiffy sono tutti basati sull'idea che devono essere moduli minimalisti indipendenti che eseguono piccole quantità di lavoro molto rapidamente e passano la richiesta al prossimo componente della pipeline. Dopo che l'ultimo componente ha terminato l'elaborazione della richiesta, segnala il contenitore servlet "completando" la richiesta e inviandola al client.

Problemi correlati