2012-07-29 8 views
10

Tengo un cliente node.js (10.177.62.7) que solicita algunos datos del servicio http rest del servidor (10.177.0.1). El cliente simplemente está utilizando node.js http.request() method (agent = false). El cliente está en la caja de Ubuntu 11.10.El cliente envía el ACUSE FINAL retrasado (~ 500ms) al servidor

¿Por qué el cliente envía FIN ACK después de 475ms? ¿Por qué es tan lenta? Debería enviar FIN ACK inmediatamente. Tengo muchas situaciones como esta. Alrededor del 1% del tráfico total se solicita con FIN ACK retrasada.

La CPU inactiva en el cliente es de aproximadamente el 99%, por lo que nada está agotando la CPU.

¿Cómo se soluciona esto? ¿Qué podría ser? ¿Hay alguna opción sysctl que necesite sintonizar?

En la captura de pantalla segunda columna es el tiempo transcurrido entre los paquetes.

Link to bigger picture.

enter image description here

+0

Suprimí mi respuesta sobre HTTP keep-alive ya que fue definitivamente descartada. Sin embargo, no puedo pensar en ninguna otra respuesta. El FIN debería apagarse tan pronto como el socket esté cerrado. –

+0

@AlanCurry Pero el * FIN/ACK * solo se apagará cuando el cliente haya leído el FIN entrante y haya decidido cerrar el socket, lo que podría tomar cualquier cantidad de tiempo. Este es un comportamiento de node.js, no de la pila TCP/IP. – EJP

+0

Claro, pero si está en medio de una llamada a una biblioteca de cliente http, no está haciendo keep-alive, y la carga de la CPU es del 1%, ¿por qué tarda tanto en cerrar el socket después de leer EOF? –

Respuesta

4

Este comportamiento es la característica de ACK retardado de RFC1122 TCP stack.

Normalmente, debe añadir la opción TCP_QUICKACK a su Linux TCP socket a disable delayed ACK pero creo que no es obvio con el API de JavaScript Node.js (sólo vi socket.setNoDelay para TCP_NODELAY opción).

Así que su idea de aplicar un system-wide change on TCP stack parece buena, pero no encontré ningún sysctl que coincida con este comportamiento de opción de socket. Aquí hay otro full list with explanation.

+0

Parece la respuesta correcta, a menos que haya más detalles que el OP no haya proporcionado –

+0

¡Gracias por su respuesta! Tengo algunas preguntas adicionales. Es válido para FIN ACK o solo para ACK "solo". ¿Puedes decir por qué Kernel retrasó ese FIN/ACK? En los datos de tcpflow hay exactamente un ACK por paquete proveniente del servidor. Por qué kernel retrasó FIN/ACK del cliente. Podría evitar enviar ACK a cada paquete de 'datos'. ¿Pero elige retrasar FIN/ACK? es posible? – Tereska

+0

Lea la sección 4.2.3.2 de RFC1122 ... no es específica de los paquetes FIN. Estoy de acuerdo con usted, no hay ninguna razón para retrasar un paquete FIN + ACK sin datos. Los invito a ponerse en contacto con el equipo Linux Kernel TCP en LKML o abrir el código fuente para la implementación de la lógica de ACK retrasada.Probablemente se pueda hacer una optimización y al menos un nuevo modificador sysctl para evitar ese comportamiento. –

Cuestiones relacionadas