Si usted está buscando para escribir un servidor de sockets, un buen punto de partida es el artículo C10K de Dan Kegel desde hace unos años:
http://www.kegel.com/c10k.html
También encontré la Guía del Beej Programación de la cadena a ser bastante práctico:
http://beej.us/guide/bgnet/
por último, si usted necesita una gran referencia, hay UNIX Network Programming por W. Richard Stevens et. al .:
http://www.amazon.com/Unix-Network-Programming-Sockets-Networking/dp/0131411551/ref=dp_ob_title_bk
De todos modos, para responder a su pregunta, la principal diferencia entre Apache y Nginx es que Apache utiliza un hilo por cliente con el bloqueo de E/S, mientras que Nginx es no bloqueante con un único subproceso E/S. El grupo de trabajadores de Apache reduce la sobrecarga de los procesos de inicio y desestresteo, pero aún hace que la CPU cambie entre varios subprocesos al servir a varios clientes. Nginx, por otro lado, maneja todas las solicitudes en un hilo. Cuando una solicitud necesita realizar una solicitud de red (por ejemplo, a un servidor), Nginx adjunta una devolución de llamada a la solicitud de back-end y luego trabaja en otra solicitud de cliente activo. En la práctica, esto significa que regresa al bucle de evento (epoll
, kqueue
o select
) y solicita descriptores de archivos que tengan algo que informar. Tenga en cuenta que la llamada al sistema en el bucle de evento principal es en realidad una operación de bloqueo, porque no hay nada que hacer hasta que uno de los descriptores de archivo esté listo para leer o escribir.
Así que esa es la razón principal por la cual Nginx y Tornado son eficientes para servir a muchos clientes simultáneos: solo hay un proceso (ahorrando RAM) y solo un hilo (ahorrando CPU de los interruptores de contexto). En cuanto a epoll, es solo una versión más eficiente de select. Si hay N descriptores de archivos abiertos (sockets), le permite seleccionar los que están listos para leer en O (1) en lugar de O (N). De hecho, Nginx puede usar select en lugar de epoll si lo compila con la opción --with-select_module
, y apuesto a que seguirá siendo más eficiente que Apache. No estoy tan familiarizado con las partes internas de Apache, pero un grep rápido muestra que usa select y epoll, probablemente cuando el servidor está escuchando múltiples puertos/interfaces, o si hace solicitudes de back-end simultáneas para un único cliente.
Por cierto, comencé con estas cosas tratando de escribir un servidor de socket básico y quería averiguar cómo Nginx era tan malditamente eficiente. Después de leer detenidamente el código fuente de Nginx y leer las guías/libros a los que me he vinculado anteriormente, descubrí que sería más fácil escribir módulos Nginx en lugar de mi propio servidor.Así nació Guía de la ahora semilegendario de Emiller a Nginx Módulo de Desarrollo:
http://www.evanmiller.org/nginx-modules-guide.html
(Advertencia: la guía se ha escrito contra Nginx 0,5-0,6 y API puede haber cambiado.) Si estás haciendo algo con HTTP, diría darle una oportunidad a Nginx porque ha resuelto todos los detalles peludos de tratar con clientes estúpidos. Por ejemplo, el pequeño servidor de socket que escribí para la diversión funcionó muy bien con todos los clientes, excepto Safari, y nunca entendí por qué. Incluso para otros protocolos, Nginx podría ser el camino correcto a seguir; el evento está muy bien abstraído de los protocolos, por lo que puede usar tanto HTTP como IMAP. El código base de Nginx está extremadamente bien organizado y muy bien escrito, con una excepción que cabe mencionar. No seguiría su ejemplo cuando se trata de rodar manualmente un analizador de protocolo; en su lugar, usa un generador de analizador. He escrito algunas cosas acerca del uso de un generador de analizadores sintácticos (Ragel) con Nginx aquí:
http://www.evanmiller.org/nginx-modules-guide-advanced.html#parsing
Todo esto era probablemente más información de lo que quería, pero espero que encontraré algo de él útil.
¡Eso es exactamente lo que necesito, muchas gracias! –
Omg, gracias hombre! – Caio