2015-01-09 13 views
14

L'MPM Evento non ha esattamente lo stesso design di Nginx, ma è stato chiaramente progettato per rendere i keepalive più tenibili e l'invio di file statici più veloce. Mi risulta che il MPM evento è un po 'fuorviante perché:Perché l'evento Apache MPM funziona male?

  1. Sebbene la connessione viene passato al kqueue/epoll,
  2. determinati moduli molto importanti come mod_gzip e mod_ssl bloccheranno/consumano un filo fino la risposta è fatto,
  3. e questo è un problema per file di grandi dimensioni, ma probabilmente non per i documenti HTML PHP-generato, ecc

Purtroppo, Apache continua a perdere quota di mercato, e la maggior parte benchmark sono dannando per l'evento MPM. I benchmark sono viziati o l'evento MPM è davvero negativo rispetto a Nginx? Anche con queste limitazioni, nel traffico normale (non dannoso) e nei file più piccoli, dovrebbe essere alquanto competitivo con Nginx. Ad esempio, dovrebbe essere competitivo per i documenti generati da PHP tramite php-fpm su connessioni lente perché il documento verrà memorizzato nel buffer (anche se è ssl'd e gzip'd) e inviato in modo asincrono. Sia le connessioni SSL che quelle non SSL che utilizzano la compressione o meno non dovrebbero funzionare in modo significativamente diverso da quello che avrebbero in Nginx su un tale carico di lavoro.

Quindi perché non risplende in vari benchmark? Che cosa c'è che non va? O cosa c'è che non va nei benchmark? Un sito importante lo utilizza come un appello all'autorità che può eseguire?

+2

Questa sarebbe una domanda molto migliore se avessi citato i benchmark a cui fai riferimento. Se si desidera semplicemente un'installazione rapida, la pre-fork di Apache + mod_php supererà costantemente Nginx su carichi da bassi a medi: c'è una grande differenza sotto carico pesante. Ma se vuoi capacità e prestazioni, dovresti guardare a un'architettura diversa: ATS/nginx/vernice di fronte ai tuoi server web. – symcbean

+0

@symcbean Probabilmente vero. Devo ancora trovarne uno (eccetto quello pubblicato da Apache) che sembra buono. Penso anche che tu sia troppo generoso. ATS o Varnish faranno molto poco (o essere dannosi) sui contenuti dinamici che non possono essere memorizzati nella cache. –

+0

Au contraire. L'esecuzione di un server basato su eventi di fronte a un server web pre-fork fornirà protezione contro gli attacchi di tipo sloloris e scaricherà il contenuto statico in servizio, risparmiando memoria e aumentando la capacità. La latenza aggiuntiva sul contenuto dinamico dovrebbe essere dell'ordine di un paio di millisecondi: difficilmente terrificante. Infatti, se è possibile spostare il proxy inverso più vicino ai client, si dovrebbe vedere un significativo miglioramento delle prestazioni. – symcbean

risposta

3

Per me, le differenze che dominano operative sono che nell'evento:

  • movimentatori (plugin responsabile della generazione della risposta) sono sincroni - se si sta eseguendo sia computazione o I/O essi saranno impegnare un filo
  • il nucleo deve utilizzare serrature cross-thread proteggere le strutture di dati chiave perché è multi-threaded per supportare tanti di queste richieste sincrone

Ecco perché ad alto volume server come nginx (o Apache Traffic Serv er o qualsiasi moderno proxy commerciale/ad alte prestazioni) di solito viene avanti.

IMO I proiettili nella tua domanda sono un po 'off-line, SSL e deflate non stanno davvero contribuendo molto alle differenze qui in quanto sono entrambi i filtri che non contribuiscono realmente a problemi di scalabilità o addirittura legano httpd al suo tradizionale Le API garantiscono il ciclo di vita di una richiesta o di una connessione. I filtri come questi (rispetto ai gestori o al filtro principale responsabile per l'I/O di basso livello) sono probabilmente l'ultimo dei problemi legati al modello di elaborazione.

Ma io non penso che sia così difficile da confrontare per tutti tranne i carichi di lavoro più estremi o sistemi estremamente limitati. La maggior parte dei benchmark che ho visto sono di pessima qualità, per una ragione o per l'altra.

Penso che in gran parte le persone vogliano quello che oggi chiamano un server web per essere un proxy per un server di applicazioni più sofisticato (Java EE, PHP, ecc.) E un server progettato per spostare I/O nel modo più efficiente senza che il bagaglio dell'API stia andando avere il vantaggio

+0

Devo aggiungere che sono così prevenuto che possono venire come un contributore di httpd Apache. – covener

+1

Thx! Ammetto di aver indovinato da un rapido controllo del codice e della documentazione. Avevo ragione riguardo agli handler ma sbagliavo riguardo alle specifiche, e mi mancava il blocco. Il motivo per cui ho sviluppato questi moduli è che ho potuto vedere che si tratta di un grosso problema su file statici di grandi dimensioni. Google vuole che ci spostiamo su tutto-SSL nel 2015. Posso persino vedere SSL passare al kernel perché non possiamo più solo mappare il file e inviarlo. Ma almeno in Nginx non ci derubherà dei fili a tempo pieno. Può usare ssh/gzip + epoll su alcuni thread block-by-block, magari con qualche affinità. Ho sbagliato? Gzip solleva problemi simili. –

10

È più lento di nginx perché Apache con l'evento MPM è (molto) approssimativamente equivalente a un proxy HTTP event-driven (nginx, varnish, haproxy) davanti a Apache con l'MPM worker.Event è worker, ma piuttosto che consegnare ogni nuova connessione a un thread per la sua durata, i thread dell'evento MPM passano la connessione a un thread secondario che lo spinge in una coda o lo chiude se keep-alive è spento o è scaduto.

Il vero vantaggio dell'evento su worker è l'utilizzo delle risorse. Se è necessario sostenere 1.000 connessioni simultanee, l'MPM worker ha bisogno di 1.000 thread, mentre l'evento MPM può farcela con 100 thread attivi e 900 connessioni inattive gestiti nella coda degli eventi. L'evento MPM utilizzerà una frazione delle risorse dell'MPM worker in quella ipotetica, ma lo svantaggio è ancora lì: ognuna di queste richieste è gestita da un thread separato che deve essere programmato dal kernel e come tale incorrerà nel costo di cambiare contesto.

D'altra parte abbiamo nginx che utilizza il modello di eventi stesso come suo schedulatore. Nginx semplicemente elabora quanto più lavoro su ogni connessione che può prima di passare a quello successivo. Non è richiesto alcun cambio di contesto aggiuntivo.

L'unico caso di utilizzo in cui l'evento MPM brilla davvero è quello di gestire una configurazione in cui è in esecuzione un'applicazione pesante in Apache e per conservare le risorse dei thread inattivi durante la conservazione, è necessario distribuire un proxy (come nginx) davanti all'apache. Se il tuo front end non ha altri scopi (ad esempio contenuto statico, proxy verso altri server, ecc ...), l'evento MPM gestisce che usa il caso splendidamente ed elimina la necessità di un proxy.

+0

Questo è esattamente il motivo per cui mi aspetto che funzioni bene se usi l'evento Apache MPM + PHP-fpm. Non dovrebbe fare molto o peggio di Nginx + PHP-fpm. Ma ogni benchmark dice che non è così. È tempo di fare il mio punto di riferimento. A dire il vero, avrebbero potuto applicare questa "ottimizzazione costante" a ogni MPM, incluso prefork.Nulla impedirebbe loro di utilizzare un processo master per tracciare le connessioni inattive mantenute in vita e di trasferirle a un processo nel pool solo quando attive. L'hanno fatto solo al lavoratore. –

+1

Il confronto che stavo facendo era Nginx + Apache-worker + PHP-fpm ~~ Apache-event + PHP-fpm. Nginx + PHP-fpm funzionerà sempre meglio di Apache-event + PHP-fpm perché ogni connessione FastCGI in Apache deve essere gestita da un thread separato. Se php fosse thread-safe potresti essere molto più vicino alle prestazioni di Nginx usando Apache-event + mod_php, ma ahimè, non è ... –

+0

Forse sto fraintendendo, ma la vita del thread sarà molto breve perché la maggior parte delle connessioni a php-fpm sarà breve. La risposta sarà piccola (un documento HTML è in genere 10-100k), viene bufferizzato e inviato in una modalità basata su eventi. Immagino che Nginx possa farlo interamente senza un thread per connessione con una macchina di stato che parla con php-fpm. Probabilmente lo bufferizzerebbe anche perché altrimenti ricreasse il problema che prefork ha con connessioni lente e semplicemente lo riporta a un processo php-fpm invece di un processo httpd. Non penserei che la differenza sarebbe così enorme. –

Problemi correlati