Domanda

Come si fa a determinare il miglior numero di maxSpare, minSpare e maxThreads, acceptCount ecc in Tomcat? Ci sono le migliori pratiche esistenti?

Io non capisco questo deve essere basata su hardware (ad esempio per core) e può essere solo una base per ulteriori test delle prestazioni e l'ottimizzazione su hardware specifico.

È stato utile?

Soluzione

il "quante discussioni problema" è piuttosto un problema di grande e complicato, e non si può rispondere con un semplice regola pratica.

Considerando il numero di core che avete è utile per le applicazioni multi-filettate che tendono a consumare un sacco di CPU, come il numero scricchiolio e simili. Questo è raramente il caso di una web-app, che di solito è frantumato non dalla CPU, ma anche da altri fattori.

Una limitazione comune è il ritardo tra l'utente e gli altri sistemi esterni, in particolare il vostro DB. Ogni volta che una richiesta arriva, probabilmente interrogare il database di un certo numero di volte, il che significa in streaming alcuni byte su una connessione JDBC, quindi in attesa di quei byte per arrivare al database (anche è che è su localhost c'è ancora un piccolo lag) , quindi in attesa per il DB di prendere in considerazione la nostra richiesta, quindi attendere che il database per elaborarlo (il database stesso sarà in attesa per il disco a cercare ad una determinata regione) ecc ...

Durante tutto questo tempo, il filo è inattivo, quindi un altro thread potrebbe usare facilmente che le risorse della CPU per fare qualcosa di utile. E 'abbastanza comune vedere il 40% al 80% del tempo trascorso in attesa di risposta DB.

Lo stesso accade anche sull'altro lato della connessione. Mentre un filo di tuo sta scrivendo la sua uscita al browser, la velocità della connessione del client può mantenere il thread in attesa di inattività per il browser su ACK che un certo pacchetto è stato ricevuto. (Questo è stato piuttosto un problema di qualche anno fa, kernel recenti e JVM utilizzano i buffer più grandi per evitare che le discussioni del minimo in questo modo, comunque un reverse proxy di fronte a voi server di applicazioni Web, anche semplicemente un httpd, può essere davvero utile per evitare la gente con connessione ad internet male a fare da attacchi DDOS :))

Considerando questi fattori, il numero di thread dovrebbe essere di solito molto più dei nuclei che avete. Anche su un semplice server dual o quad core è necessario configurare un paio di discussioni decine almeno.

Quindi, che cosa sta limitando il numero di thread è possibile configurare?

Prima di tutto, ogni thread (usata per) consumano un sacco di risorse. Ogni filo ha una pila, che consuma RAM. Inoltre, ogni discussione sarà effettivamente allocare roba sul mucchio per fare il suo lavoro, consumando nuovo RAM, e l'atto di passaggio tra i thread (cambio di contesto) è abbastanza pesante per il kernel JVM / OS.

Questo rende difficile per eseguire un server con migliaia di thread "senza intoppi".

Dato questo quadro, ci sono una serie di tecniche (per lo più: provare, fallire, sintonia, provare di nuovo) per determinare più o meno il numero di thread si app avrete bisogno di:

1) Cercate di capire dove le discussioni che trascorrere del tempo. Ci sono un certo numero di buoni strumenti, ma anche profilatore jvisualvm può essere un grande strumento, o un aspetto rintracciamento che produce Riassunto previsti temporizzazione. Più tempo che spendono in attesa di qualcosa di esterno, quanto più è possibile generare più thread da utilizzare in fase di inattività della CPU.

2) Determinare l'utilizzo della RAM. Dato che la JVM userà una certa quantità di memoria (in particolare lo spazio PermGen, di solito fino a un centinaio di megabyte, ancora una volta jvisualvm dirà) indipendentemente dal numero di thread di utilizzare, provare a eseguire con un filo e poi con dieci e poi con un centinaio, pur sottolineando l'applicazione con JMeter o qualsiasi altra cosa, e vedere come mucchio utilizzo crescerà. Questo può rappresentare un limite rigido.

3) Provate a determinare un bersaglio. Ciascuna richiesta utente necessita di un filo da trattare. Se il tempo medio di risposta è di 200ms per "get" (sarebbe meglio non prendere in considerazione il caricamento di immagini, CSS e altre risorse statiche), quindi ogni thread è in grado di servire 4/5 pagine al secondo. Se ogni utente si prevede di "click" ogni 3/4 secondi (dipende, si tratta di un browser game o un sito con un sacco di testi lunghi?), Allora un thread sarà "servire 20 utenti simultanei", qualunque cosa significhi. Se nell'ora di punta si dispone di 500 utenti singoli che colpiscono il tuo sito in 1 minuto, allora avete bisogno abbastanza thread per gestire questo.

4) Crash Test il limite massimo. Usa JMeter, configure un server con un sacco di discussioni su una macchina virtuale di riserva, e vedere come il tempo di risposta peggiorerà quando si va oltre un certo limite. Più che hardware, l'attuazione filo del sistema operativo di base è importante, ma non importa quello che colpirà un punto in cui la CPU trascorrere più tempo a cercare di capire quale thread per l'esecuzione di effettivamente in esecuzione, e che numer non è così incredibilmente alta.

5) Si consideri come le discussioni avranno un impatto altri componenti. Ogni thread probabilmente utilizzare una (o forse più di uno) di connessione al database, è il database in grado di gestire 50/100/500 connessioni simultanee? Anche se si sta utilizzando un cluster di server sharded NoSQL, fa il sufficiente larghezza di banda del server farm offerta tra quelle macchine? Cos'altro verrà eseguito sulla stessa macchina con il server web-app? Anache httpd? calamaro? il database stesso? un proxy caching locale al database come Mongos o memcached?

Sono sistemi in produzione visto con solo 4 fili + 4 filetti di ricambio, causa il lavoro fatto da quel server era semplicemente quello di ridimensionare le immagini, quindi è stato quasi il 100% per la CPU, e altri configurato su più o meno lo stesso hardware con un paio di centinaia di fili, causa la webapp stava facendo un sacco di chiamate SOAP a sistemi esterni e trascorrere la maggior parte del suo tempo in attesa di risposte.

Oce aver determinato la ca. le discussioni minimo e massimo ottimali per voi webapp, allora io di solito configurare in questo modo:

1) In base ai vincoli RAM, altre risorse esterne ed esperimenti di commutazione di contesto, v'è un massimo assoluto che non deve essere raggiunto. Quindi, utilizzare maxThreads di limitarla a circa la metà o 3/4 di quel numero.

2) Se l'applicazione è ragionevolmente veloce (ad esempio, espone REST servizi web che di solito inviare una risposta è a pochi millesimi di secondo), quindi è possibile configurare un grande acceptCount, fino allo stesso numero di maxThreads. Se si dispone di un sistema di bilanciamento del carico di fronte al vostro server di applicazioni Web, impostare un piccolo acceptCount, è meglio per il bilanciamento del carico per vedere le richieste non accettate e passare a un altro server che mettere gli utenti in attesa su un uno già occupato.

3) Poiché iniziare un thread è (ancora) considerato un'operazione pesante, utilizzare minSpareThreads avere qualche filo pronta quando ore di punta arrivano. Questo dipende ancora una volta dal tipo di carico che si aspettano. E 'anche ragionevole avere MinSpareThreads, MaxSpareThreads e la configurazione maxThreads in modo che un numero esatto di fili è sempre pronto, mai bonificata, e le prestazioni sono prevedibili. Se si esegue Tomcat su un computer dedicato, è possibile sollevare MinSpareThreads e MaxSpareThreads senza alcun pericolo di monopolizzano altri processi, altrimenti sintonia giù causa le discussioni sono risorse condivise con il resto dei processi in esecuzione sulla maggior parte del sistema operativo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top