Asynchronous-IO vs Asynchronous-Request Processing en java

En este artículo, intento explicar la diferencia entre el procesamiento Async-IO y Async-Request en la solicitud HTTP en el mundo Java.

En el mundo anterior a Java 1.4 , Java proporciona una API para enviar / recibir datos a través del conector de red. Los autores originales de JVM asignaron este comportamiento de API a la API de sockets del SO, casi uno a uno.

Entonces, ¿cuál es el comportamiento del socket del sistema operativo? El sistema operativo proporciona la API de programación de Socket, que tiene llamadas de bloqueo de envío / recepción . Dado que java es solo un proceso que se ejecuta sobre Linux (OS), este programa java tiene que usar esta api de bloqueo proporcionada por OS.

El mundo estaba feliz y los desarrolladores de Java comenzaron a usar la API para enviar / recibir datos. Pero tenían que mantener un hilo de Java para cada socket (cliente).

Todo el mundo estaba escribiendo su propia versión de los servidores HTTP. Compartir código se estaba volviendo difícil, el mundo Java exigía una estandarización.

Introduce la especificación del servlet java.

Antes de continuar, definamos algunos términos:

Desarrollador de servidores Java : personas que utilizan la API de socket Java e implementan el protocolo http como tomcat.

Desarrollador de aplicaciones java: personas que están creando aplicaciones comerciales sobre Tomcat.

VOLVER AHORA

Una vez que la especificación del servlet de Java entró en el mundo, dijo:

Estimados desarrolladores de servidores Java, proporcionen un método como el siguiente:

doGet(inputReq, OutPutRes)

para que el desarrollador de aplicaciones Java pueda implementar doGety escribir su lógica empresarial. Una vez que el "desarrollador de aplicaciones" quiera enviar el response, puede llamarOutPutRes.write().

Una cosa a tener en cuenta: dado que la API de socket está bloqueando, OutPutRes.write () también lo está. Además, la limitación adicional era que el objeto de respuesta se confirma al salir del método doGet .

Debido a estas limitaciones, las personas tenían que usar un hilo para procesar una solicitud.

Pasó el tiempo e internet se apoderó del mundo. un hilo por solicitud comenzó a mostrar limitaciones.

Problema 1:

El modelo de subproceso por solicitud falla cuando hay pausas largas durante el procesamiento de cada solicitud.

Por ejemplo: la obtención de datos del subservicio lleva mucho tiempo.

En tal situación, el hilo está mayormente inactivo y JVM puede quedarse sin hilo fácilmente.

Problema 2:

Las cosas empeoraron con la conexión persistente http1.1. Al igual que con la conexión persistente, la conexión TCP subyacente se mantendrá activa y el servidor debe bloquear un hilo por conexión.

Pero, ¿por qué el servidor tiene que bloquear un hilo por conexión?

Dado que el sistema operativo proporciona una api Recv de socket de bloqueo, el jvm tiene que llamar al método Recv de bloqueo del sistema operativo para escuchar más solicitudes en la misma conexión tcp del cliente.

¡El mundo demandaba una solución!

La primera solución vino del creador de JVM. Introdujeron NIO ( ASYNC-IO ). Nio es la API sin bloqueo para enviar / recibir datos a través de socket.

Algunos antecedentes: elEl sistema operativo junto con la API de socket de bloqueo también proporciona una versión sin bloqueo de la API de socket.

Pero, ¿cómo proporciona el sistema operativo eso? ¿Bifurca un hilo internamente y ese hilo se bloquea ???

La RESPUESTA es no ... el sistema operativo indica al hardware que interrumpa cuando hay datos para leer o escribir.

NIO permitió al " desarrollador de servidor Java"para abordar el problema 2 de bloquear un hilo por conexión TCP . Dado que NIO es una conexión persistente HTTP, el hilo no requiere que se bloquee en la llamada recv . En cambio, ahora puede procesarlo solo cuando hay datos para procesar. Esto permitió que un hilo monitoreara / manejara una gran cantidad de conexiones persistentes.

La segunda solución vino de la especificación del servlet. Servlet Spec obtuvo una actualización e introdujeron soporte asíncrono (procesamiento de solicitudes asíncronas ).

AsyncContext acontext = req.startAsync();
IMPORTANTE: Esta actualización eliminó la limitación de confirmar el objeto de respuesta al completar el método doGet .

Esto permitió al " desarrollador de aplicaciones Java" abordar el problema 1, descargando el trabajo en subprocesos en segundo plano. Ahora, en lugar de mantener el hilo esperando durante la pausa larga, el hilo puede usarse para manejar otras solicitudes.

CONCLUSIÓN:

Async-IO en Java básicamente utiliza la versión sin bloqueo en la API de sockets del SO.

El procesamiento de solicitudes asíncronas es básicamente la estandarización de la especificación del servlet sobre cómo procesar más solicitudes con un hilo.

REFERENCIAS:

//www.scottklement.com/rpg/socktut/tutorial.pdf

//stackoverflow.com/questions/15217524/what-is-the-difference-between-thread-per-connection-vs-thread-per-request

Motivación del artículo: aprendizaje en equipo / intercambio de conocimientos