L'approccio dell'ascensore alla scalabilità è all'interno di una singola macchina. Il ridimensionamento tra le macchine è un argomento più ampio e impegnativo. La risposta breve è: Scala e Lift non fanno nulla per aiutare o ostacolare il ridimensionamento orizzontale.
Per quanto riguarda gli attori all'interno di una singola macchina, Lift raggiunge una migliore scalabilità poiché una singola istanza può gestire più richieste simultanee rispetto alla maggior parte degli altri server. Per spiegare, devo prima sottolineare i difetti nel classico modello di gestione thread-per-request. Abbi pazienza, questo richiederà qualche spiegazione.
Un framework tipico utilizza un thread per soddisfare una richiesta di pagina. Quando il client si connette, il framework assegna un thread a un pool. Quel thread quindi fa tre cose: legge la richiesta da un socket; esegue alcuni calcoli (potenzialmente coinvolgendo l'I/O nel database); e invia una risposta sul socket. Ad ogni passo, il thread finirà per bloccarsi per un po 'di tempo. Durante la lettura della richiesta, può bloccarsi mentre attende la rete. Quando esegue il calcolo, può bloccare su disco o I/O di rete. Può anche bloccare durante l'attesa del database. Infine, durante l'invio della risposta, può bloccare se il client riceve i dati lentamente e le finestre TCP vengono riempite. Nel complesso, il thread potrebbe spendere il 30 - 90% del tempo bloccato. Trascorre il 100% del suo tempo, tuttavia, su quella richiesta.
Una JVM può supportare solo molti thread prima che rallenti davvero. La schedulazione dei thread, la contesa per le entità a memoria condivisa (come i pool di connessione e i monitor) ei limiti del sistema operativo nativo impongono restrizioni sul numero di thread che una JVM può creare.
Bene, se la JVM è limitata nel numero massimo di thread e il numero di thread determina il numero di richieste simultanee che un server può gestire, il numero di richieste simultanee sarà determinato dal numero di thread.
(Ci sono altri problemi che possono imporre limiti inferiori --- GC botte, per esempio. Thread sono un fattore limitante fondamentale, ma non l'unica!)
Ascensore disaccoppia filo dalle richieste. In Lift, una richiesta fa non legare una discussione. Piuttosto, un thread esegue un'azione (come leggere la richiesta), quindi invia un messaggio a un attore. Gli attori sono una parte importante della storia, perché sono programmati tramite thread "leggeri". Un pool di thread viene utilizzato per elaborare i messaggi all'interno degli attori. È importante evitare il blocco delle operazioni all'interno degli attori, quindi questi thread vengono restituiti rapidamente al pool.(Si noti che questo pool non è visibile all'applicazione, fa parte del supporto di Scala per gli attori.) Una richiesta attualmente bloccata sul database o sull'I/O del disco, ad esempio, non mantiene occupato un thread di gestione richieste. Il thread di gestione richieste è disponibile, quasi immediatamente, per ricevere più connessioni.
Questo metodo per il disaccoppiamento delle richieste dai thread consente a un server di sollevamento di avere molte più richieste simultanee rispetto a un server di thread per richiesta. (Vorrei anche sottolineare che la libreria Grizzly supporta un approccio simile senza attori.) Più richieste contemporanee significa che un singolo server Lift può supportare più utenti rispetto a un normale server Java EE.
Questo è davvero un argomento enorme, penso che sia meglio focalizzare la risposta a specifiche aree del software server –