Domanda

Tornadoweb e Nginx sono server web popolari per il momento e molti benchmarking mostrano di avere una prestazione migliore di Apache in determinate circostanze. Quindi la mia domanda è:

"Epoll" è la ragione più essenziale che li rende così veloce? E cosa posso imparare da questo se voglio scrivere un buon server socket?

È stato utile?

Soluzione

Se stai cercando di scrivere un server socket, un buon punto di partenza è l'articolo C10K di Dan Kegel da qualche anno fa:

http://www.kegel.com/c10k.html

Ho anche trovato la guida di Beej alla programmazione di rete piuttosto utile:

http://beej.us/guide/bgnat/

Infine, se hai bisogno di un ottimo riferimento, c'è una programmazione di rete UNIX di W. Richard Stevens ET. al.:

http://www.amazon.com/unix-network-programming-sockets-networking/dp/0131411551/ref=dp_ob_title_bk

Ad ogni modo, per rispondere alla tua domanda, la differenza principale tra Apache e Nginx è che Apache utilizza un thread per client con I/O bloccante, mentre Nginx è a thread singolo con I/O non bloccante. Il pool di lavoratori di Apache riduce il sovraccarico dei processi di avvio e dedica, ma fa comunque il passaggio della CPU tra più thread quando si serve più client. Nginx, d'altra parte, gestisce tutte le richieste in un thread. Quando una richiesta deve effettuare una richiesta di rete (diciamo, a un backend), Nginx allega un callback alla richiesta di back -end e quindi lavora su un'altra richiesta di client attivo. In pratica, questo significa che ritorna al loop evento (epoll, kqueue, o select) e chiede descrittori di file che hanno qualcosa da segnalare. Si noti che il sistema di sistema nel ciclo di eventi principali è in realtà un'operazione di blocco, perché non c'è nulla da fare fino a quando uno dei descrittori di file non è pronto per la lettura o la scrittura.

Questo è il motivo principale per cui Nginx e Tornado sono efficienti nel servire molti clienti simultanei: c'è sempre un solo processo (salvezza della RAM) e solo un thread (salvando così la CPU dagli switch di contesto). Per quanto riguarda Epoll, è solo una versione più efficiente di Select. Se ci sono n descrittori di file aperti (prese), ti consente di scegliere quelli pronti per la lettura in O (1) anziché O (N) tempo. In effetti, Nginx può usare selezionare invece di epoll se lo compili con il --with-select_module Opzione e scommetto che sarà comunque più efficiente di Apache. Non ho familiarità con gli interni Apache, ma un Grep rapido mostra che usa Select ed Epoll, probabilmente quando il server ascolta più porte/interfacce o se fa richieste simultanee di back -end per un singolo client.

Per inciso, ho iniziato con questa roba che cercava di scrivere un server socket di base e volevo capire come NGINX fosse così efficiente. Dopo aver potuto tramite il codice sorgente Nginx e aver letto quelle guide/libri a cui ho collegato sopra, ho scoperto che sarebbe più facile scrivere moduli Nginx anziché il mio server. Così è nato la Guida di Emiller ormai-legendaria allo sviluppo del modulo Nginx:

http://www.evanmiller.org/nginx-modules-guide.html

(Attenzione: la guida è stata scritta contro NGINX 0,5-0,6 e le API potrebbero essere cambiate.) Se stai facendo qualcosa con HTTP, direi che prova a NGINX uno scatto perché ha elaborato tutti i dettagli pelosi della gestione di stupidi clienti. Ad esempio, il piccolo server socket che ho scritto per divertimento ha funzionato alla grande con tutti i client, tranne Safari, e non ho mai capito perché. Anche per altri protocolli, Nginx potrebbe essere la strada giusta per andare; L'evento è abbastanza ben astratto dai protocolli, motivo per cui può proxy HTTP e IMAP. La base di codice Nginx è estremamente ben organizzata e molto ben scritta, con una sola eccezione che porta menzione. Non seguirei il suo vantaggio quando si tratta di strappare a mano un parser di protocollo; Invece, usa un generatore di parser. Ho scritto alcune cose sull'uso di un generatore di parser (Ragel) con Nginx qui:

http://www.evanmiller.org/nginx-modules-guide-advanced.html#parsing

Tutto ciò era probabilmente più informazioni di quanto volevi, ma spero che ne troverai alcune utili.

Altri suggerimenti

Sì e no. Mentre entrambi usano Epoll, è tecnicamente che entrambi utilizzino un ciclo di eventi per gestire le richieste. Puoi trovare maggiori informazioni su quali sono i loop di eventi e su come vengono utilizzati Wikipedia.

Guardare libevent (usato da Gevent, generalmente più veloce e più stabile del tornado) o Libev per implementazioni.

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