Pregunta

Estamos intentando ajustar una aplicación que acepta mensajes a través de TCP y también usa TCP para algunos de sus mensajes internos. Durante las pruebas de carga, notamos que el tiempo de respuesta se degrada significativamente (y luego se detiene por completo) a medida que se realizan más solicitudes simultáneas al sistema. Durante este tiempo, vemos muchas conexiones TCP en estado TIME_WAIT y alguien sugirió reducir la variable de entorno TIME_WAIT de su valor predeterminado de 60 segundos a 30.

De lo que entiendo , el TIME_WAIT setting esencialmente establece el tiempo que un recurso TCP está disponible para el sistema nuevamente después de que se cierra la conexión.

No soy un "tipo de red" y saber muy poco sobre estas cosas. Necesito mucho de lo que hay en esa publicación enlazada, pero "tonto" un poco.

  • Creo que entiendo por qué el valor TIME_WAIT no puede establecerse en 0, pero ¿puede establecerse de manera segura en 5? ¿Qué hay de 10? Lo que determina un "seguro" ajuste para este valor?
  • ¿Por qué el valor predeterminado para este valor es 60? Supongo que las personas mucho más inteligentes que yo tenían buenas razones para seleccionar esto como un valor razonable por defecto.
  • ¿Qué más debo saber sobre los posibles riesgos y beneficios de anular este valor?
¿Fue útil?

Solución

La tupla especifica una conexión TCP (IP de origen, puerto de origen, IP de destino, puerto de destino).

La razón por la cual hay un estado TIME_WAIT después del cierre de la sesión es porque todavía puede haber paquetes en vivo en la red en su camino hacia usted (o de usted que puede solicitar una respuesta de algún tipo). Si volviera a crear esa misma tupla y apareciera uno de esos paquetes, se trataría como un paquete válido para su conexión (y probablemente causaría un error debido a la secuencia).

Por lo tanto, el tiempo TIME_WAIT generalmente se establece para duplicar la antigüedad máxima de los paquetes. Este valor es la edad máxima a la que se les permitirá llegar a sus paquetes antes de que la red los descarte.

Eso garantiza que, antes de que se te permita crear una conexión con la misma tupla, todos los paquetes pertenecientes a encarnaciones anteriores de esa tupla estarán muertos.

Eso generalmente dicta el valor mínimo que debe usar. La edad máxima de los paquetes está determinada por las propiedades de la red, un ejemplo es que la vida útil de los satélites es mayor que la vida útil de la LAN, ya que los paquetes tienen mucho más que recorrer.

Otros consejos

Por lo general, solo el punto final que emite un 'cierre activo' debe pasar al estado TIME_WAIT. Entonces, si es posible, haga que sus clientes emitan el cierre activo que dejará el TIME_WAIT en el cliente y NO en el servidor.

Ver aquí: http://www.serverframework.com/asynchronousevents/2011/01/time-wait-and-its-design-implications-for-protocols-and-scalable-servers.html y http://www.isi.edu/touch/pubs/infocomm99/infocomm99-web/ para más detalles (la explicación posterior también explica por qué no siempre es posible debido al diseño del protocolo que no tiene en cuenta TIME_WAIT).

Pax tiene razón sobre los motivos de TIME_WAIT y por qué debe tener cuidado al reducir la configuración predeterminada.

Una mejor solución es variar los números de puerto utilizados para el extremo de origen de sus sockets. Una vez que haga esto, realmente no le importará el tiempo de espera para enchufes individuales.

Para las tomas de escucha, puede usar SO_REUSEADDR para permitir que la toma de escucha se una a pesar de las tomas TIME_WAIT.

En Windows, usted puede cambiar it a través del registro :

; Set the TIME_WAIT delay to 30 seconds (0x1E)

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP\Parameters]
"TcpTimedWaitDelay"=dword:0000001E

configurar tcp_reuse es más útil que cambiar time_wait, siempre que tenga el parámetro (kernels 3.2 y superiores, desafortunadamente eso descalifica todas las versiones de RHEL y XenServer).

Dejar caer el valor, particularmente para usuarios conectados a VPN, puede resultar en la recreación constante de túneles proxy en la conexión saliente. Con la configuración predeterminada de Netscaler (XenServer), que es inferior a la configuración predeterminada de Linux, Chrome a veces tendrá que recrear el túnel proxy hasta una docena de veces para recuperar una página web. Las aplicaciones que no vuelven a intentarlo, como Maven y Eclipse P2, simplemente fallan.

El motivo original para el parámetro (evitar la duplicación) fue redundante por un TCP RFC que especifica la inclusión de marca de tiempo en todas las solicitudes de TCP.

He estado probando la carga de una aplicación de servidor (en Linux) utilizando un programa de prueba con 20 hilos.

En 959,000 ciclos de conexión / cierre tuve 44,000 conexiones fallidas y muchos miles de sockets en TIME_WAIT.

Configuré SO_LINGER en 0 antes de la llamada de cierre y en ejecuciones posteriores del programa de prueba no hubo fallas de conexión y menos de 20 sockets en TIME_WAIT.

TIME_WAIT podría no ser el culpable.

int listen(int sockfd, int backlog);

De acuerdo con el Volumen 1 de programación de red de Unix, la acumulación se define como la suma de la cola de conexión completa y la cola de conexión incompleta.

Digamos que la acumulación es 5. Si tiene 3 conexiones completadas (estado ESTABLECIDO) y 2 conexiones incompletas (estado SYN_RCVD), y hay otra solicitud de conexión con SYN. La pila TCP simplemente ignora el paquete SYN, sabiendo que será retransmitido en otro momento. Esto podría estar causando la degradación.

Al menos eso es lo que he estado leyendo. ;)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top