2012-01-11 14 views

Respuesta

2

para no bloquear IO se debe utilizar cuando se puede manejar la petición, enviar para su procesamiento en algún otro contexto de ejecución (subproceso diferente, llamada RPC a otro servidor, algún otro mecanismo asíncrono) y suelte el web- el hilo del servidor para manejar más solicitudes entrantes. Cuando se complete el procesamiento de la respuesta, se invocará un hilo de manejo de respuesta y enviará la respuesta al cliente.

Recomendaría leer netty documentation para una mejor comprensión del concepto.

En cuanto a un mayor rendimiento: cuando el servidor envía/recibe grandes cantidades de datos, todos los conmutadores de contexto y el paso de datos entre subprocesos, realmente puede dañar el rendimiento general. Piénselo de esta manera: recibe una solicitud grande (solicitud PUT con un archivo grande). Todo lo que necesita hacer es guardarlo en el disco y regresar OK. Comenzar a lanzarlo entre hilos podría dar como resultado pocas operaciones más de copia de memoria que hubieran sido necesarias en caso de que acabara de tirarlo al disco en el mismo hilo. Y manejar esta operación de manera asincrónica no mejoraría el rendimiento: aunque podría haber liberado el hilo de manejo de solicitudes al grupo de subprocesos del servidor web y dejarlo procesar otras solicitudes, su cuello de botella de rendimiento principal es su disco IO, y en este caso - intentando para guardar más archivos simultáneamente, solo haría las cosas más lentas.

Espero haber sido lo suficientemente claro. Por favor, siéntase libre de hacer más preguntas en los comentarios si necesita más explicaciones.

+0

Entonces, ¿puedo concluir que la mayor ventaja que proporciona el no bloqueo es la capacidad, es decir, la cantidad de solicitudes simultaneas que se pueden tratar por servidor, no el rendimiento total o la velocidad por procesamiento de solicitudes? Si agrego más servidores en el clúster, ¿puedo lograr el mismo resultado con una mejor velocidad y rendimiento utilizando el bloqueo io, siempre que la arquitectura de mi aplicación tenga una buena escalabilidad horizontal? – xiefei

+1

Aproximadamente, sí. Por supuesto, todo su servidor usa algún recurso compartido (base de datos, sistema de archivos compartido, algún servicio de back-end), estaría limitado por su velocidad, pero si no tiene nada de eso, agregar más servidores lo mejorará. rendimiento en la mayoría de los casos. Además, programar de manera asíncrona es más difícil y mucho más propenso a errores. –

+1

Por otro lado, agregar más servidores al clúster es expansivo y probablemente no lo ayude a hacer frente a una gran cantidad de pequeñas solicitudes que no requieren casi ningún servidor (Por ejemplo, el servidor web que usa IO no bloqueante es mucho más resiliente a los ataques de DOS: responde con el código de error adecuado a los atacantes y hace lo que necesita hacer para las solicitudes válidas) –

3

La primera afirmación es verdadera solo cuando el número de solicitudes simultáneas es relativamente pequeño (más bien en decenas que en miles). Se trata de usar muchos hilos (bloqueo) en lugar de uno o pocos hilos (sin bloqueo). Digamos que desea escribir una aplicación que solo descarga un archivo del servidor remoto. Si su aplicación necesita descargar solo un archivo a la vez, solo necesita un hilo. Pero si tiene un rastreador que ejecuta miles de solicitudes HTTP, entonces necesita tener miles de hilos (o usar un número limitado de hilos + NIO en su lugar). Para una cantidad tan grande de subprocesos, el problema es el cambio de contexto, que puede ralentizar su aplicación de forma espectacular (por lo tanto, para este número de solicitudes simultáneas, NIO es mejor).

Pero volvamos a su pregunta. ¿Por qué NIO puede ser más lento en términos de rendimiento de datos sin formato? La razón es la cantidad de tiempo de CPU utilizado por las aplicaciones impulsadas por NIO. Para ese caso en el modelo de bloqueo, su código está haciendo una sola cosa: esperar datos (ejecuta la operación recv() en un bucle). En la aplicación NIO, la lógica es mucho más complicada: en un bucle, el código usa el selector para seleccionar un conjunto de claves (lo que implica una llamada al sistema epoll_wait en Linux, Oracle JVM), luego iterar por el conjunto, seleccionar un canal para cada clave y luego lea los datos de la operación de canal (lectura() en el sistema operativo). En el modelo de bloqueo estándar, todo lo que hace es ejecutar la función del sistema recv(). En resumen: la aplicación impulsada por NIO en tal caso usa más tiempo de CPU y genera más operaciones de cambio de modo debido a una mayor cantidad de llamadas al sistema (al decir el cambio de modo me refiero al cambio de usuario a modo núcleo). Por lo tanto, el tiempo necesario para descargar el archivo será mayor.

+0

Pero si casi todos los hilos están bloqueados esperando E/S entonces no hay cambio de contexto, pensé ... ¿así que el cambio de contexto cuesta realmente el problema con el uso de hilos para muchas solicitudes simultáneas? –

+0

@DobesVandermeer el programador de sistema operativo tiene que gastar recursos en subprocesos inactivos de todos modos, para controlar si necesitan ser activados. Así que sí, los hilos inactivos también tienen un costo. – vadipp

Cuestiones relacionadas