sirve servlet que para español contenedor concepto animal java servlets jetty nio nonblocking

java - servlet - tomcat animal



¿De qué manera Jetty y otros contenedores aprovechan NIO mientras cumplen con la especificación de Servlet? (1)

No lo tienes exactamente correcto. Cuando embarcadero utiliza un conector NIO (y 9 solo admite NIO), funciona de la siguiente manera:

  1. Estado inactivo como unos pocos hilos (1-4 dependiendo de # núcleos) llamando al selector, buscando actividad IO. Esto se ha escalado a más de 1,000,000 de conexiones en Jetty.
  2. Cuando el selector ve la actividad IO, llama a un método de control en la conexión, que puede:

    • algo más ha registrado que está bloqueado esperando IO para esta conexión, por lo que en ese caso el selector simplemente despierta a quien haya sido bloqueado.
    • de lo contrario, se envía un hilo para manejar la conexión.
  3. Si se envía un hilo, intentará leer la conexión y analizarlo. Lo que sucede ahora depende de si la conexión es http, spdy, http2 o websocket.

    • para http, si los encabezados de solicitud están completos, el hilo continúa para llamar al manejo de la solicitud (eventualmente esto llega al servlet) sin esperar ningún contenido.
    • para http2 / spdy se requiere otro despacho, pero vea la discusión sobre la estrategia de comer lo que mata en la lista: http://dev.eclipse.org/mhonarc/lists/jetty-dev/msg02166.html
    • para websocket se llama al manejo de mensajes.
  4. Una vez que un subproceso se envía a un servlet, se ve como el servlet IO está bloqueando, pero debajo del nivel de HttpInputStream y HttpOutputStream todo el IO es asíncrono con devoluciones de llamada. La API de bloqueo usa una devolución de llamada de bloqueo especial para lograr el bloqueo. Esto significa que si el servlet elige usar async IO, entonces simplemente está pasando por alto la devolución de llamada de bloqueo y utilizando la API asincrónica más o menos directamente.

  5. Un servlet puede suspender el uso de request.startAsync, en cuyo caso el hilo enviado se devuelve al grupo de subprocesos, pero la conexión asociada no se marca como interesada en IO. Se puede realizar Async IO, pero un evento AsyncContext necesita reasignar un hilo o volver a registrar la conexión para la actividad IO una vez que se completa el ciclo asincrónico.

Esta vista se complica un poco con http2 y spdy, que se multiplexan, por lo que pueden implicar un envío adicional.

Cualquier marco HTTP que no despache puede ir realmente rápido en código de referencia, pero cuando se enfrenta a una aplicación real que puede hacer cosas tontas como bloquear bases de datos, sistema de archivos, servicios REST, etc. ... entonces la falta de despacho solo significa que uno la conexión puede contener todas las otras conexiones en el sistema.

Para obtener más información sobre cómo maneja embarcadero async y despacho ver:

Soy nuevo en NIO, y estoy tratando de descubrir cómo Jetty aprovecha NIO.

Tengo entendido cómo los contenedores de servlets tradicionales que usan el servicio de Bloqueo IO solicitan lo siguiente:

  1. Una solicitud llega
  2. Se asigna un subproceso para procesar la solicitud y se invoca el método de servlet ( doGet etc.)
  3. El método Servlet recibe un InputStream y OutputStream
  4. El método de servlet se lee desde InputStream y escribe en OutputStream
  5. InputStream y OutputStream básicamente están vinculados a las transmisiones respectivas del Socket subyacente

¿Qué es diferente cuando se usa un conector NIO? Mi conjetura es a lo largo de las siguientes líneas:

  1. Una solicitud llega
  2. Jetty usa el conector NIO y almacena en búfer toda la solicitud de forma asíncrona
  3. Una vez que se ha leído la solicitud, envuelva el buffer en un InputStream
  4. Crear un búfer de respuesta vacío (envuelto en un OutputStream )
  5. Asigne un hilo e invoque el método de servlet ( doGet etc.) entregando las secuencias de contenedor anteriores
  6. El método de servlet escribe en la secuencia de respuesta envuelta (en búfer) y regresa del método de servlet
  7. Jetty usa NIO para escribir el contenido del búfer de respuesta en el SocketChannel subyacente

De la documentación de Jetty, encontré lo siguiente:

SelectChannelConnector : este conector utiliza búferes NIO eficientes con un modelo de subprocesamiento sin bloqueo. Jetty utiliza búferes Direct NIO y asigna subprocesos solo a conexiones con solicitudes. La sincronización simula el bloqueo de la API de servlet y cualquier contenido no descargado al final del manejo de la solicitud se escribe de forma asíncrona.

No estoy seguro de entender qué significa Synchronization simulates blocking for the servlet API .