2012-01-23 8 views
7

Estamos enfrentando un problema inusual en nuestra aplicación, en el último mes nuestra aplicación alcanzó un estado irrecuperable, Se recuperó después de reiniciar la aplicación.Volcado de subprocesos que muestra el estado Runnable, pero está colgado durante bastante tiempo

Antecedentes: nuestra aplicación realiza una consulta de base de datos para buscar información y esta base de datos está alojada en un nodo diferente.

Caso problemático: cuando se analizó el volcado de subprocesos, vemos que todos los subprocesos están en estado ejecutable obteniendo los datos de la base de datos, pero no terminó incluso después de 20 minutos.

Coloque el reinicio de la aplicación como se esperaba de todos los subprocesos recuperados. Y el uso de la CPU también era normal.

a continuación es el volcado de hilo

ThreadPool: 2: 47" prio = 3 tid = 0x0000000007334000 nid = 0x5F runnable [0xfffffd7fe9f54000] java.lang.Thread.State: RUNNABLE en oracle.jdbc. driver.T2CStatement.t2cParseExecuteDescribe (Método nativo) en oracle.jdbc.driver.T2CPreparedStatement.executeForDescribe (T2CPreparedStatement.java:518) en oracle.jdbc.driver.T2CPreparedStatement.executeForRows (T2CPreparedStatement.java:764) de Ora

All threads in the same state. 

Preguntas:

  1. lo que podría ser la razón de este estado?
  2. cómo recuperarse en este caso?
+0

se puede comprobar usando descarga hilo analizador http://mchr3k.github.com/javathreaddumpanalyser/ – GustyWind

+0

¿Alguna vez encontrar una solución para esto? Estoy teniendo exactamente el mismo problema, y ​​es recurrente cada pocas semanas/meses. – Kayaman

+0

¿Está seguro de que una tubería no se rompió en algún lugar? –

Respuesta

1

Probablemente esté esperando datos de red del servidor de la base de datos. Los subprocesos de Java en espera (bloqueados) en E/S están descritos por la JVM como en el estado RUNNABLE, aunque desde el punto de vista del programa están bloqueados.

0

Los métodos nativos permanecen siempre en estado RUNNABLE (bien, a menos que cambie el estado del método nativo, pero esto no cuenta).

El método se puede bloquear en IO, en cualquier otro evento en espera o simplemente en una tarea intensa de CPU larga ... o en un bucle sin fin. Puede hacer su propia selección.

cómo recuperarse en este caso?

soltar la conexión de oracle.

1

Como ya se ha mencionado, los métodos nativos siempre se pueden ejecutar, ya que la JVM no los conoce ni se preocupa por ellos.

Los controladores de Oracle en el lado del cliente no tienen tiempo de espera del socket por defecto. Esto significa que si tiene problemas de red, el socket de bajo nivel del cliente puede "quedarse" ahí para siempre, lo que da como resultado un grupo de conexiones maximizadas. También puede verificar el tráfico de red hacia el servidor de Oracle para ver si incluso transmite datos o no.

Al utilizar el Thin Client, puede establecer oracle.jdbc.ReadTimeout, pero no sé cómo hacerlo para el cliente grueso (oci) que utiliza, no estoy familiarizado con él.

¿Qué hacer? Investigue cómo puede especificar el tiempo de espera de lectura para el controlador ojdbc grueso, y observe las excepciones relacionadas con el tiempo de espera de la conexión, que señalarán claramente problemas de red. Si puede cambiar la fuente, puede envolver las llamadas y volver a intentar la sesión cuando atrape las SQLExcepciones relacionadas con el tiempo de espera.

Para solucionar rápidamente el problema, finalice la conexión en el servidor Oracle manualmente.

Vale la pena verificar la contención de la sesión, tal vez una consulta bloquea estas sesiones. Si encuentra uno, verá qué objeto de base de datos causa el problema.

0

¿Se está colgando el sistema o JVM? Si es configurable y, si es posible, reduzca la cantidad de hilos/conexiones paralelas.

El hilo simplemente desperdicia ciclos de CPU al esperar IO. Sí, lamentablemente su CPU está ocupada por los hilos que esperan una respuesta de DB.

0
  1. ¿Su código maneja manualmente la transacción? Si entonces, tal vez parte del código no confirmó() después de cambiar los datos. O tal vez alguien ejecutó la consulta de modificación de datos directamente a través de PLSQL o algo así y no se comprometió, y eso lleva a que se cuelgue toda la operación de lectura.

  2. Cuando experimente que "colgado" y DB se ha recuperado del estado, ¿ha revisado los datos si algunos de ellos se han retrotraído? Preguntar esto desde que dijiste "Se recuperó después de reiniciar la aplicación". Está sucediendo cuando el controlador JDBC cambió las cosas, pero no se comprometió, y se agotó el tiempo de espera ... La operación DB se revertirá. (Puede ser diferente en función de la configuración, aunque)

Cuestiones relacionadas