Je suis nouveau dans le framework Akka et je construis une application serveur HTTP sur Netty + Akka.
Jusqu'à présent, mon idée est de créer un acteur pour chaque type de demande. Par exemple. J'aurais un acteur pour un POST vers/ma-ressource et un autre acteur pour un GET vers/ma-ressource.
Là où je suis confus, c'est comment je dois procéder pour la création d'acteurs? Devrais-je:
Créer un nouvel acteur pour chaque demande (j'entends par là pour chaque demande dois-je faire un TypedActor.newInstance () de l'acteur approprié)? Combien coûte la création d'un nouvel acteur?
Créer une instance de chaque acteur au démarrage du serveur et utiliser cette instance d'acteur pour chaque demande? J'ai lu qu'un acteur ne peut traiter qu'un seul message à la fois, alors cela ne pourrait-il pas être un goulot d'étranglement?
Faites autre chose?
Merci pour tout commentaire.
Eh bien, vous créez un acteur pour chaque instance d'état mutable que vous souhaitez gérer.
Dans votre cas, cela pourrait être un seul acteur si my-resource
est un objet unique et vous souhaitez traiter chaque demande en série - cela garantit facilement que vous ne renvoyez des états cohérents qu'entre les modifications.
Si (plus probablement) vous gérez plusieurs ressources, un acteur par instance de ressource est généralement idéal, sauf si vous utilisez plusieurs milliers de ressources. Bien que vous puissiez également exécuter des acteurs par demande, vous vous retrouverez avec un design étrange si vous ne pensez pas à l'état auquel ces demandes accèdent - par exemple si vous créez un seul acteur par POST, vous vous demanderez comment les empêcher de modifier simultanément la même ressource, ce qui indique clairement que vous avez mal défini vos acteurs.
J'ai généralement des acteurs de demande/réponse assez triviaux dont le but principal est d'abstraire la communication avec des systèmes externes. Leur communication avec les acteurs "instance" est alors normalement limitée à une paire requête/réponse pour effectuer l'action réelle.
Les options 1) ou 2) ont leurs deux inconvénients. Alors, utilisons les options 3) Routage (Akka 2.0 +)
Le routeur est un élément qui agit comme un équilibreur de charge, acheminant les demandes vers d'autres acteurs qui exécuteront la tâche requise.
Akka fournit différentes implémentations de routeur avec une logique différente pour acheminer un message (par exemple SmallestMailboxPool ou RoundRobinPool).
Chaque routeur peut avoir plusieurs enfants et sa tâche consiste à superviser sa boîte aux lettres pour décider plus loin où acheminer le message reçu.
//This will create 5 instances of the actor ExampleActor
//managed and supervised by a RoundRobinRouter
ActorRef roundRobinRouter = getContext().actorOf(
Props.create(ExampleActor.class).withRouter(new RoundRobinRouter(5)),"router");
Cette procédure est bien expliquée dans ce blog .
Si vous utilisez Akka, vous pouvez créer un acteur par demande. Akka est extrêmement mince sur les ressources et vous pouvez créer littéralement des millions d'acteurs sur un tas JVM assez ordinaire. De plus, ils ne consomment cpu/stack/threads que lorsqu'ils font réellement quelque chose.
Il y a un an, j'ai fait un comparaison entre la consommation de ressources des acteurs standard basés sur les threads et les événements. Et Akka est encore mieux que la base d'événements.
Un des gros points d'Akka à mon avis est qu'il vous permet de concevoir votre système comme "un acteur par utilisation" où les systèmes d'acteurs antérieurs forçaient souvent vous devez "utiliser uniquement les acteurs pour les services partagés" en raison de la surcharge des ressources.
Je vous recommanderais d'opter pour l'option 1.
C'est une option tout à fait raisonnable, mais son adéquation dépend des spécificités du traitement de votre demande.
Oui, bien sûr.
Dans de nombreux cas, la meilleure chose à faire serait de n'avoir qu'un seul acteur répondant à chaque demande (ou peut-être un acteur par type de demande), mais la seule chose que cet acteur fait est de transmettre la tâche à un autre acteur (ou de générer un Future
) qui fera réellement le travail.
Pour étendre la gestion des demandes en série, ajoutez un acteur maître ( Superviseur ) qui à son tour déléguera aux acteurs de travail ( Enfants ) ( mode round-robin) ).