Estoy tratando de entender los detalles más bajos de los servidores web. Me pregunto si un servidor, por ejemplo Apache, está sondeando continuamente nuevas solicitudes o si funciona mediante algún tipo de sistema de interrupción. Si es una interrupción, ¿qué está provocando la interrupción? ¿Es el controlador de la tarjeta de red?
networking
webserver
embedded
user2202911
fuente
fuente
Respuestas:
La respuesta corta es: algún tipo de sistema de interrupción. Esencialmente, usan el bloqueo de E / S, lo que significa que duermen (bloquean) mientras esperan nuevos datos.
El servidor crea un socket de escucha y luego bloquea mientras espera nuevas conexiones. Durante este tiempo, el núcleo pone el proceso en un estado de suspensión interrumpible y ejecuta otros procesos. Este es un punto importante: tener la encuesta de proceso continuamente desperdiciaría la CPU. El kernel puede usar los recursos del sistema de manera más eficiente al bloquear el proceso hasta que haya trabajo que hacer.
Cuando llegan nuevos datos a la red, la tarjeta de red emite una interrupción.
Al ver que hay una interrupción de la tarjeta de red, el núcleo, a través del controlador de la tarjeta de red, lee los nuevos datos de la tarjeta de red y los almacena en la memoria. (Esto debe hacerse rápidamente y generalmente se maneja dentro del controlador de interrupciones).
El núcleo procesa los datos recién llegados y los asocia con un socket. Un proceso que está bloqueando en ese socket se marcará como ejecutable, lo que significa que ahora es elegible para ejecutarse. No necesariamente se ejecuta de inmediato (el núcleo puede decidir ejecutar otros procesos aún).
En su tiempo libre, el núcleo activará el proceso del servidor web bloqueado. (Ya que ahora es ejecutable).
El proceso del servidor web continúa ejecutándose como si no hubiera pasado el tiempo. Su llamada de sistema de bloqueo regresa y procesa cualquier dato nuevo. Entonces ... vaya al paso 1.
fuente
accept
. Son (¡afortunadamente, o apestaría totalmente!) Tareas independientes que se ejecutan asincrónicamente. A medida que entran las conexiones, se colocan en una cola de donde lasaccept
saca. Solo si no hay ninguno, se bloquea.Hay bastantes detalles "inferiores".
Primero, considere que el núcleo tiene una lista de procesos y, en cualquier momento, algunos de estos procesos se están ejecutando y otros no. El kernel le permite a cada proceso en ejecución una porción de tiempo de CPU, luego lo interrumpe y pasa al siguiente. Si no hay procesos ejecutables, entonces el núcleo probablemente emitirá una instrucción como HLT a la CPU que suspende la CPU hasta que haya una interrupción de hardware.
En algún lugar del servidor hay una llamada al sistema que dice "dame algo que hacer". Hay dos amplias categorías de formas en que esto se puede hacer. En el caso de Apache, llama
accept
a un socket que Apache ha abierto anteriormente, probablemente escuchando en el puerto 80. El núcleo mantiene una cola de intentos de conexión y se agrega a esa cola cada vez que se recibe un TCP SYN . La forma en que el núcleo sabe que se recibió un TCP SYN depende del controlador del dispositivo; Para muchas NIC probablemente haya una interrupción de hardware cuando se reciben datos de la red.accept
le pide al kernel que me devuelva la próxima iniciación de conexión. Si la cola no estaba vacía,accept
solo regresa de inmediato. Si la cola está vacía, el proceso (Apache) se elimina de la lista de procesos en ejecución. Cuando se inicia una conexión más tarde, el proceso se reanuda. Esto se llama "bloqueo", porque para el proceso que lo llama,accept()
parece una función que no regresa hasta que tiene un resultado, lo que podría pasar en algún momento a partir de ahora. Durante ese tiempo, el proceso no puede hacer nada más.Una vez que
accept
regresa, Apache sabe que alguien está intentando iniciar una conexión. Luego llama a fork para dividir el proceso de Apache en dos procesos idénticos. Uno de estos procesos continúa para procesar la solicitud HTTP, el otro llamaaccept
nuevamente para obtener la siguiente conexión. Por lo tanto, siempre hay un proceso maestro que no hace más que llamaraccept
y generar subprocesos, y luego hay un subproceso para cada solicitud.Esta es una simplificación: es posible hacer esto con subprocesos en lugar de procesos, y también es posible hacerlo de
fork
antemano para que haya un proceso de trabajo listo cuando se recibe una solicitud, lo que reduce la sobrecarga de inicio. Dependiendo de cómo esté configurado Apache, puede hacer cualquiera de estas cosas.Esa es la primera categoría amplia de cómo hacerlo, y se llama bloqueo de E / S porque el sistema llama como
accept
yread
ywrite
que operan en sockets suspenderá el proceso hasta que tengan algo que devolver.La otra forma amplia de hacerlo se llama IO sin bloqueo o basada en eventos o asincrónica . Esto se implementa con llamadas al sistema como
select
oepoll
. Cada uno de ellos hace lo mismo: les das una lista de sockets (o, en general, descriptores de archivos) y lo que quieres hacer con ellos, y el núcleo se bloquea hasta que esté listo para hacer una de esas cosas.Con este modelo, puede decirle al núcleo (con
epoll
): "Indíqueme cuándo hay una nueva conexión en el puerto 80 o nuevos datos para leer en cualquiera de estas 9471 otras conexiones que he abierto".epoll
bloquea hasta que una de esas cosas esté lista, entonces lo haces. Entonces repites. Las llamadas al sistema comoaccept
yread
ywrite
no cuadra, en parte porque cada vez que se llama a ellos,epoll
acabo de decir que están dispuestos de modo que no habría razón para bloquear, y también porque cuando se abre la toma o el archivo que especifica que ellos quieren en modo sin bloqueo, por lo que esas llamadas fallarán enEWOULDBLOCK
lugar de bloquearse.La ventaja de este modelo es que solo necesita un proceso. Esto significa que no tiene que asignar una pila y estructuras de kernel para cada solicitud. Nginx y HAProxy usan este modelo, y es una gran razón por la que pueden manejar tantas más conexiones que Apache en hardware similar.
fuente