2011-01-21 14 views
16

Estoy tratando de entender qué hace que Nginx sea tan rápido, y tengo algunas preguntas.nginx: ¿Es multiproceso pero utiliza múltiples procesos?

Como lo entiendo, Apache o bien genera un nuevo proceso para servir a cada solicitud o genera un nuevo hilo para servir a cada petición. Dado que cada nuevo hilo comparte el espacio de direcciones virtuales, el uso de la memoria mantiene subidas si hay un número de solicitudes simultáneas entrantes.

Nginx resuelve esto teniendo solo un proceso de escucha (Maestro), con un solo hilo de ejecución Y 2 o 3 (número es configurable) procesos de trabajo. Este proceso/subproceso maestro está ejecutando un bucle de evento. Efectivamente esperando cualquier solicitud entrante. Cuando llega una solicitud, entrega esa solicitud a uno de los procesos de trabajo.

Por favor, corríjanme si mi entendimiento anterior no es correcta

Si lo anterior es correcto, entonces tengo algunas preguntas:

1.) ¿No es el proceso de trabajo que va a generar múltiples hilos y va a encontrarse con el mismo problema que apache?

2.) O es nginx rápido porque su arquitectura basada en eventos utiliza sin bloqueo-IO debajo de todo. Tal vez el proceso de trabajo engendra hilos que hacen solo sin bloqueo-IO, ¿o sí?

3.) ¿Qué "exactamente" es "arquitectura basada en eventos", puede alguien realmente simplificarlo, por soemone como yo de entender. ¿Sólo se refiere a no-bloqueo-io o algo más también?

Obtuve una referencia de c10k, estoy tratando de resolverlo, pero no creo que se trate de un evento basado en el arco. parece más para IO sin bloqueo.

+0

IO no bloqueante requiere una arquitectura basada en eventos. –

+0

FYI - En caso de que esté interesado en profundizar - He escrito un blog sobre la respuesta junto con otros materiales + videos aquí: http://planetunknown.blogspot.com/2011/02/why-nginx-is-faster- than-apache.html – PlanetUnknown

Respuesta

17

No es muy complicado desde el punto de vista conceptual. Trataré de ser claro, pero tengo que simplificar un poco.

servidores basados ​​El evento (como nginx y lighttpd) utilizan una envoltura alrededor de un sistema de monitorización de eventos. Por ejemplo. lighttpd usa libevent para abstraer el sistema de monitoreo de eventos de alta velocidad más avanzado (ver libev también).

El servidor mantiene un registro de todas las conexiones sin bloqueo que tiene (la escritura y lectura) usando una máquina de estados simple para cada conexión. El sistema de monitoreo de eventos notifica el proceso del servidor cuando hay nuevos datos disponibles o cuando puede escribir más datos. Es como un select() con esteroides, si conoce la programación del zócalo. El proceso servidor simplemente envía el archivo solicitado usando alguna función avanzada como sendfile() donde sea posible o convierte la solicitud a un proceso CGI utilizando un socket para comunicación (este socket será monitoreado con el sistema de monitoreo de eventos como las otras conexiones de red)

This enlace como una gran cantidad de información sobre los aspectos internos de nginx, por las dudas. Espero que ayude.

+0

Gracias Ass3mbler. Creo que eso me ayudó a entenderlo. – PlanetUnknown

+0

@PlanetUnknow Estoy muy contento de que haya ayudado. Si necesita más información, solo pregúnteme, he trabajado muchas veces para modificar la fuente de lighttpd. Si está bien, ¿podría aceptar mi respuesta, por favor? ¡Gracias! – Ass3mbler

+0

Gracias Ass3mbler. Creo que eso me ayudó a entenderlo. De modo que el proceso maestro escucha el tráfico entrante y los procesos de trabajo ejecutan bucles de eventos (registrando eventos y respondiendo cuando ocurre uno). En un resumen, ¿es correcto? – PlanetUnknown

46

Apache utiliza varios subprocesos para proporcionar cada solicitud con su propio hilo de ejecución. Esto es necesario para evitar el bloqueo cuando se utilizan E/S síncronas.

Nginx utiliza sólo E/S asíncrona, lo que hace que el bloqueo no sea un problema. La única razón por la cual nginx usa múltiples procesos es para hacer un uso completo de sistemas multi-core, multi-CPU e hyper-threading. Incluso con soporte SMP, el kernel no puede programar un único hilo de ejecución en múltiples CPU.Requiere al menos un proceso o hilo por CPU lógica.

Así que la diferencia es Nginx requiere sólo procesos de trabajo suficientes para obtener el beneficio completo de leche desnatada en polvo, mientras que la arquitectura de Apache hace necesaria crear un nuevo hilo (cada uno con su propia pila de alrededor de ~ 8 MB) por solicitud. Obviamente, en alta concurrencia, Apache utilizará mucha más memoria y sufrirá una sobrecarga mayor al mantener un gran número de subprocesos.

+3

¡respuesta muy clara! – clime

+0

¿Por qué no utilizar varios subprocesos para hacer uso de CPU multinúcleo? – spockwang

+0

@spockwang De hecho, usan un trabajador para el núcleo. _ ** La configuración NGINX recomendada en la mayoría de los casos (ejecutar un proceso de trabajo por núcleo de CPU) hace el uso más eficiente de los recursos de hardware. ** _ de [documentos NGINX] (https://www.nginx.com/blog/inside -nginx-how-we-designed-for-performance-scale) – gabrielgiussi

6

Apache no genera un nuevo hilo para cada solicitud. Mantiene una caché de subprocesos o un grupo de procesos prehibertados a los que proporciona solicitudes. El número de solicitudes concurrentes está limitado por el número de hijos/hilos, sí, pero apache no está generando un nuevo subproceso/hijo por cada solicitud que sería ridículamente lento (incluso con subprocesos, la creación y el desmantelamiento de cada solicitud serían demasiado lentos))

Nginx usa un modelo maestro-trabajador. El proceso maestro trata de cargar la configuración y crear/destruir/mantener trabajadores. Al igual que apache, comienza con una serie de procesos pre-bifurcados que ya están ejecutando cada uno de los cuales es un trabajador (y uno de ellos es el proceso "maestro"). CADA proceso de trabajo comparte un conjunto de sockets de escucha. Cada proceso de trabajo acepta conexiones y las procesa, pero cada trabajador puede manejar MILES de conexiones a la vez, a diferencia de apache, que solo puede manejar 1 conexión por trabajador.

La forma en que nginx logra esto es a través de "multiplexación". No utiliza libevent, utiliza un bucle de eventos personalizado que fue diseñado específicamente para nginx y creció en desarrollo con el desarrollo del software nginx. La multiplexación funciona mediante el uso de un bucle para "incrementar" a través de un fragmento de programa por fragmento que opera en una pieza de datos/nueva conexión/lo que sea por conexión/objeto por iteración de bucle. Todo se basa en componentes como Epoll() kqueue() y select(). Lo que debe leer en

Cuestiones relacionadas