java - puertos - time_wait close_wait
Solucionar problemas de conexiones bloqueadas en el estado CLOSE_WAIT (6)
Tengo una aplicación Java ejecutándose en WebLogic 11g en Windows, que luego de varios días deja de responder. Un síntoma sospechoso que he notado es que una gran cantidad de conexiones (alrededor de 3000) aparecen en netstat
con un estado CLOSE_WAIT incluso cuando el servidor está inactivo. Como el servidor de aplicaciones administra las conexiones de los clientes, no estoy seguro de lo que está causando esto. También realizamos una serie de llamadas al servicio web que vuelven al mismo servidor, pero creo que esas conexiones se cierran correctamente. ¿Qué otra cosa podría causar esto y cómo se puede solucionar un problema como este?
El estado CLOSE_WAIT
significa que el otro lado ha iniciado una conexión cerrada, pero la aplicación en el lado local aún no ha cerrado el socket.
Parece que tienes un error en tu aplicación local.
El problema fue un error desencadenado al establecer "Usar JSSE SSL" en verdadero en webLogic. Usar la propia implementación de SSL de WebLogic en lugar de JSSE no es un problema para nuestra aplicación, así que simplemente desmarqué esa configuración y el problema desapareció.
Encontré esta cita sobre los acumuladores CLOSE_WAIT: "Algo impide el progreso en la sesión HTTP (estamos atascados, por lo que nunca terminamos llamando), o se ha introducido algún error que impide que el socket se cierre. Hay un número de formas en que esto puede suceder ".
Piensa: ¿Hay alguna forma en que tu aplicación se pueda estancar al procesar una solicitud? ¿O WebLogic en sí?
Examine: ¿Puede hacer vuelcos de subprocesos de Java (kill -SIGQUIT se puede utilizar para eso en Oracle JVM para Linux) para intentar ver si, de hecho, alguno de sus subprocesos se estanca?
Examine el lado del cliente: primero, descubra la dirección IP o el nombre de host de los clientes que están conectados a los sockets CLOSE_WAIT. Luego, vea si algo sospechoso está sucediendo en esos clientes.
Esto podría significar que no está llamando "cerrar" en un socket desde su llamada accept ().
He estado teniendo el mismo problema y he estado estudiando tomas de corriente para deshacerme de este problema.
Permítanme decir algunas palabras, pero antes debo decir que no soy un programador de Java.
No explicaré qué es close_wait, ya que Brian White ya dijo todo lo que debería decirse.
Para evitar close_wait, debe asegurarse de que su servidor no cierra la conexión después de que devuelve la respuesta porque quien se desconecte primero se queda atascado en close_wait y time_wait. Entonces, si su servidor se atasca en close_wait, me dice que se está desconectando después de enviar la respuesta.
Deberías evitar eso haciendo algunas cosas.
1 - Si su aplicación cliente no está utilizando el protocolo http 1.1, debe configurarlo para usarlo debido a la opción ''keep-alive
header''.
2 - Si su cliente está ejecutando http 1.1 y eso no funciona, o si debe usar http 1.0, debe establecer la propiedad del encabezado de la solicitud de conexión:
connection: keep-alive
Esto le dice al servidor que ni el cliente ni el servidor deben desconectarse después de completar una solicitud. Al hacer eso, su servidor no se desconectará después de cada solicitud que reciba.
3 - En tu cliente, reutiliza tu socket. Si está creando muchos clientes de sockets en un bucle, por ejemplo, debe crear un socket y usarlo cada vez que necesite enviar una solicitud. El enfoque que utilicé en mi aplicación es tener un grupo de sockets y obtener un socket disponible (que ya está conectado al servidor y tiene la propiedad keep-alive). Luego lo uso y cuando termine lo vuelvo a poner en la piscina para que sea reutilizable.
4 - Si realmente necesita desconectarse después de enviar una solicitud, asegúrese de que su cliente lo haga y mantenga la connection: keep-alive
.
Y sí, puede tener problemas cuando tiene un montón de close_waits u time_waits en el lado del servidor.
Mira este [enlace] [1] que explica qué es keep-alive
.
Espero que esto haya sido útil. Con esas cosas logré resolver mi problema.
[1]: http://www.w3.org/Protocols/HTTP/1.1/draft-ietf-http-v11-spec-01.html#Persistent Connections
CLOSE_WAIT
es el estado en que se encuentra la máquina de estado TCP local cuando el host remoto envía un FIN (cierra su conexión) pero la aplicación local no ha hecho lo mismo y envió una respuesta FIN. Todavía es posible que la máquina local envíe datos en este momento, aunque el cliente no puede recibirlos (a menos que haya estado a la mitad de la conexión).
Cuando el host remoto se cierra (envía un FIN), su aplicación local obtendrá un evento de algún tipo (es un evento de "lectura" en el zócalo en la biblioteca base C) pero leer de esa conexión arrojará un error para indicar que el la conexión ha cerrado. En este punto, la aplicación local debería cerrar la conexión.
Sé poco sobre Java y nada sobre WebLogic, pero supongo que es posible que la aplicación no esté manejando el error de lectura correctamente y, por lo tanto, nunca cierre la conexión.