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.
Ceci est vraiment un sujet énorme, je pense que vous feriez mieux de concentrer votre réponse à des domaines spécifiques du logiciel serveur –