2009-03-16 4 views
53

Je veux connaître les raisons techniques pour lesquelles le châssis Web de l'élévateur a des performances et une évolutivité élevées? Je sais qu'il utilise scala, qui a une bibliothèque d'acteur, mais selon les instructions d'installation, la configuration par défaut est avec jetty. Alors, utilise-t-il la bibliothèque d'acteurs à l'échelle?Pourquoi le framework Web de levage est-il évolutif?

L'évolutivité est désormais intégrée dès la sortie de la boîte. Il suffit d'ajouter des serveurs et des nœuds supplémentaires et cela évoluera automatiquement, est-ce ainsi que cela fonctionne? Peut-il gérer plus de 500 000 connexions simultanées avec des serveurs de support. J'essaye de créer un cadre de services Web au niveau de l'entreprise, qui peut battre ce qui existe et est facile à mettre à l'échelle, configurable et maintenable. Ma définition de la mise à l'échelle consiste simplement à ajouter plus de serveurs et vous devriez être en mesure d'accepter la charge supplémentaire.

Merci

+1

Ceci est vraiment un sujet énorme, je pense que vous feriez mieux de concentrer votre réponse à des domaines spécifiques du logiciel serveur –

Répondre

3

jetée peut-être le point d'entrée, mais l'acteur finit par le service de la demande, je suggère d'avoir un regard sur l'exemple de twitter-esque, « s'enfuir » pour voir comment vous seriez en mesure de créer un service très évolutif. IIRC, c'est l'une des choses qui a fait remarquer les gens de Twitter.

170

L'approche de Lift pour l'évolutivité est dans une seule machine. La mise à l'échelle sur les machines est un sujet plus vaste et plus difficile. La réponse courte est: Scala et Lift ne font rien pour aider ou empêcher la mise à l'échelle horizontale.

En ce qui concerne les acteurs au sein d'une même machine, Lift obtient une meilleure évolutivité car une instance unique peut gérer plus de demandes simultanées que la plupart des autres serveurs. Pour expliquer, je dois d'abord souligner les failles dans le modèle classique de gestion de thread par requête. Ours avec moi, cela va demander quelques explications.

Une structure type utilise un thread pour gérer une demande de page. Lorsque le client se connecte, le framework affecte un thread à un pool. Ce thread fait alors trois choses: il lit la requête depuis une socket; il fait un peu de calcul (impliquant potentiellement des E/S à la base de données); et il envoie une réponse sur le socket. À peu près à chaque étape, le fil finira par bloquer pendant un certain temps. En lisant la requête, il peut bloquer en attendant le réseau. Lors du calcul, il peut bloquer sur le disque ou les E/S réseau. Il peut également bloquer en attendant la base de données. Enfin, lors de l'envoi de la réponse, il peut bloquer si le client reçoit des données lentement et que les fenêtres TCP sont remplies. Dans l'ensemble, le thread peut passer de 30 à 90% de son temps bloqué. Cependant, il consacre 100% de son temps à cette demande. Une JVM peut uniquement prendre en charge autant de threads avant qu'elle ne ralentisse vraiment. La programmation des threads, la contention pour les entités à mémoire partagée (comme les pools de connexions et les moniteurs) et les limites du système d'exploitation natif imposent toutes des restrictions sur le nombre de threads qu'une JVM peut créer. Eh bien, si la JVM est limitée dans son nombre maximum de threads, et le nombre de threads détermine combien de requêtes simultanées un serveur peut gérer, alors le nombre de requêtes simultanées sera déterminé par le nombre de threads.

(Il existe d'autres problèmes qui peuvent imposer des limites inférieures --- raclée de GC, par exemple. Les threads sont un facteur limitant fondamental, mais pas le seul!)

Lift découple fil de demandes. Dans Ascenseur, une demande ne pas bloquer un fil. Plutôt, un thread fait une action (comme lire la requête), puis envoie un message à un acteur. Les acteurs sont une partie importante de l'histoire, car ils sont programmés via des threads "légers". Un pool de threads est utilisé pour traiter les messages dans les acteurs. Il est important d'éviter les opérations de blocage à l'intérieur des acteurs, de sorte que ces threads soient rapidement renvoyés dans le pool.(Notez que ce pool n'est pas visible pour l'application, cela fait partie du support de Scala pour les acteurs.) Une requête qui est actuellement bloquée sur une base de données ou une E/S disque, par exemple, ne garde pas occupé un thread de gestion de requête. Le thread de gestion des requêtes est disponible, presque immédiatement, pour recevoir plus de connexions.

Cette méthode de découplage des requêtes des threads permet à un serveur Lift d'avoir beaucoup plus de demandes simultanées qu'un serveur de thread par requête. (Je tiens également à souligner que la bibliothèque Grizzly prend en charge une approche similaire sans acteurs.) Plus de demandes simultanées signifie qu'un seul serveur Lift peut prendre en charge plus d'utilisateurs qu'un serveur Java EE standard.

+5

Je veux plus de votes jusqu'à vous donner. C'était une réponse parfaite. –

+23

Je pense que vous êtes victime d'un questionnement rapide. Votre réponse est de loin préférable à la question elle-même mérite. –

+1

@mtnygard: vous dites "il est important d'éviter les opérations de blocage à l'intérieur des acteurs". Que faire si j'ai besoin de faire des E/S qui pourraient potentiellement bloquer pendant un certain temps? Dois-je lancer un autre thread? –

20

à mtnyguard

« Scala et Lift ne font rien pour aider ou nuire à l'échelle horizontale »

est-ce pas tout à fait raison. L'ascenseur est un cadre hautement statefull. Par exemple, si un utilisateur demande un formulaire, il peut uniquement envoyer la demande à la même machine d'où provient le formulaire, car l'action de traitement de formulaire est enregistrée dans l'état du serveur.

Et ceci est actuellement une chose qui entrave l'évolutivité d'une certaine manière, car ce comportement est incompatible avec l'architecture de rien partagée. Nul doute que la portance est très performante, mais la performance et l'évolutivité sont deux choses différentes. Donc, si vous voulez redimensionner horizontalement avec lift, vous devez définir des sessions collantes sur le loadbalancer qui redirigera un utilisateur pendant une session vers la même machine.

+12

Oui ...c'est vrai et Foursquare et Novell Pulse démontrent tous les deux que l'exigence de collant de Lift n'est pas un problème pour la mise à l'échelle horizontale ... et avec le prochain Lift Cluster Manager commercial, la gestion du cluster sera encore plus facile. –

+1

Où est Lift Cluster Manager? – Lukasz

1

J'aime vraiment la réponse de @ dre car il indique correctement l'état de l'ascenseur étant un problème potentiel pour l'extensibilité horizontale.

Le problème - Au lieu de me décrire le tout à nouveau, consultez la discussion (pas le contenu) sur ce post. http://javasmith.blogspot.com/2010/02/automagically-cluster-web-sessions-in.html

La solution serait comme @dre ladite configuration de session collante sur l'équilibreur de charge sur le front et en ajoutant plus d'instances. Mais comme la gestion des requêtes dans lift est faite en combinaison thread + acteur, vous pouvez vous attendre à ce qu'une instance gère plus de requêtes que les frameworks normaux. Cela donnerait un avantage sur les sessions persistantes dans d'autres frameworks. La capacité de l'instance individuelle à traiter plus peut vous aider à l'échelle

  • vous avez l'intégration d'ascenseur Akka qui serait un autre avantage à cela.
Questions connexes