Cómo resolver el problema de punto muerto en ColdFusion 9: coldfusion.util.AbstractCache $ Lock

He estado tratando de resolver un problema en el que la ejecución de ciertos scripts causa un punto muerto, colocando todas las solicitudes posteriores en el limbo, usando hasta el 99.9% de la CPU y finalmente bloqueando el servidor de manera efectiva.

Aquí hay un ejemplo de seguimiento de pila para una de las solicitudes que se ha puesto en el limbo (esperando eternamente):

Thread Stack Trace
Trace Time: 21:00:44.463 06-Jun-2012
Request ID: 6131
Script Name: http://www.example.com/allreviews.cfm
Started: 21:00:21.225 06-Jun-2012
Exec Time: 23238ms
Memory Used: (24%)230,667KB
Memory Free: 701,428KB
Thread ID: 0x191e (6430)
Thread Name: jrpp-494
Priority: 5
Hashcode: 1081611879
State: WAITING

"jrpp-494" prio=5 in Object.wait()

java.lang.Object.wait(Object.java:???)[Native Method]
- waiting on <0x9253305> (a coldfusion.util.AbstractCache$Lock)
java.lang.Object.wait(Object.java:485)
coldfusion.util.AbstractCache.fetch(AbstractCache.java:46)
coldfusion.util.SoftCache.get_statsOff(SoftCache.java:133)
coldfusion.util.SoftCache.get(SoftCache.java:81)
coldfusion.runtime.TemplateClassLoader.findClass(TemplateClassLoader.java:609)
coldfusion.runtime.RuntimeServiceImpl.getFile(RuntimeServiceImpl.java:785)
coldfusion.runtime.RuntimeServiceImpl.resolveTemplatePath(RuntimeServiceImpl.java:766)
coldfusion.tagext.lang.CustomTag.setName(CustomTag.java:21)
cfApplication2ecfm456206189._factor0(/srv/www/htdocs/www.example.com/www/Application.cfm:28)
cfApplication2ecfm456206189.runPage(/srv/www/htdocs/www.example.com/www/Application.cfm:1)
coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:231)
coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:416)
coldfusion.filter.CfincludeFilter.invoke(CfincludeFilter.java:65)
coldfusion.filter.CfincludeFilter.include(CfincludeFilter.java:33)
coldfusion.filter.ApplicationFilter.invoke(ApplicationFilter.java:279)
coldfusion.filter.RequestMonitorFilter.invoke(RequestMonitorFilter.java:48)
coldfusion.filter.MonitoringFilter.invoke(MonitoringFilter.java:40)
coldfusion.filter.PathFilter.invoke(PathFilter.java:94)
coldfusion.filter.ExceptionFilter.invoke(ExceptionFilter.java:70)
coldfusion.filter.ClientScopePersistenceFilter.invoke(ClientScopePersistenceFilter.java:28)
coldfusion.filter.BrowserFilter.invoke(BrowserFilter.java:38)
coldfusion.filter.NoCacheFilter.invoke(NoCacheFilter.java:46)
coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:38)
coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22)
coldfusion.filter.CachingFilter.invoke(CachingFilter.java:62)
coldfusion.CfmServlet.service(CfmServlet.java:200)
coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:89)
jrun.servlet.FilterChain.doFilter(FilterChain.java:86)
com.intergral.fusionreactor.filter.FusionReactorCoreFilter.doHttpServletRequest(FusionReactorCoreFilter.java:503)
com.intergral.fusionreactor.filter.FusionReactorCoreFilter.doFusionRequest(FusionReactorCoreFilter.java:337)
com.intergral.fusionreactor.filter.FusionReactorCoreFilter.doFilter(FusionReactorCoreFilter.java:246)
com.intergral.fusionreactor.filter.FusionReactorFilter.doFilter(FusionReactorFilter.java:121)
jrun.servlet.FilterChain.doFilter(FilterChain.java:94)
coldfusion.monitor.event.MonitoringServletFilter.doFilter(MonitoringServletFilter.java:42)
coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:46)
jrun.servlet.FilterChain.doFilter(FilterChain.java:94)
jrun.servlet.FilterChain.service(FilterChain.java:101)
jrun.servlet.ServletInvoker.invoke(ServletInvoker.java:106)
jrun.servlet.JRunInvokerChain.invokeNext(JRunInvokerChain.java:42)
jrun.servlet.JRunRequestDispatcher.invoke(JRunRequestDispatcher.java:286)
jrun.servlet.ServletEngineService.dispatch(ServletEngineService.java:543)
jrun.servlet.jrpp.JRunProxyService.invokeRunnable(JRunProxyService.java:203)
jrunx.scheduler.ThreadPool$DownstreamMetrics.invokeRunnable(ThreadPool.java:320)
jrunx.scheduler.ThreadPool$ThreadThrottle.invokeRunnable(ThreadPool.java:428)
jrunx.scheduler.ThreadPool$UpstreamMetrics.invokeRunnable(ThreadPool.java:266)
jrunx.scheduler.WorkerThread.run(WorkerThread.java:66)

Si está interesado, puede ver el seguimiento completo de la pila con lo que llamaré 'el script de bloqueo' en la parte superior y todos los demás que lo esperan.

Cuando encontré este problema por primera vez, no tenía los rastros de la pila. Publiqué la pregunta: " Cuando ColdFusion está maximizando la CPU, ¿cómo puedo saber qué está masticando / ahogando?". Recibí muchas respuestas útiles y al observar los rastros de la pila pude determinar que eran los mismos tres scripts los que causaban este problema de punto muerto una y otra vez.

En cada caso, la línea superior en 'el script de bloqueo' dice:

coldfusion.compiler.ClassReader.skipFully(ClassReader.java:79)

Y todas las demás solicitudes están obstruidas detrás de ella y tienen la siguiente línea en sus respectivos seguimientos de pila:

- waiting on <0x9253305> (a coldfusion.util.AbstractCache$Lock)

Una cosa que me molestaba era por qué no se respetaba el tiempo de espera de mi solicitud; estos guiones se colgarían para siempre y nunca morirían. WTF, ¿verdad? Así que tuve que hacerlo yo mismo. Entonces, cuando mato 'el script de bloqueo', los otros son liberados del limbo. En ese momento, si están por debajo del tiempo de espera de la solicitud, terminan el procesamiento y, si lo superan (lo que generalmente son todos), simplemente proceden al tiempo de espera. Pero no se agotarán por su cuenta y las solicitudes solo se acumularán hasta que se usen los hilos activos y la cola de hilos esté llena y todo se bloquee.

Obviamente, matarlos manualmente cada vez que se solicitan no es una solución, por lo que mi esposa siempre me recuerda "depurar, depurar, depurar". Utilizando un condicional, <cfabort>entré y descubrí que estaba llegando a través de Application.cfm, a través de header.cfm y hasta <cfinclude>el script del problema. Si pongo el guión del problema <cfabort> dentro (incluso en la parte superior), no se anulará y se producirá el problema de punto muerto. Si lo coloco justo antes de la inclusión, la solicitud se anularía y se evitaría el problema de punto muerto. Extraño.

No hay código entre estos dos lugares, ¿verdad? Justo antes de la inclusión y justo dentro de la inclusión debería ser funcionalmente equivalente, ¿no? Probablemente no, porque claramente algo está sucediendo allí.

No estoy usando ninguna <cflock>etiqueta. El bloqueo que está ocurriendo parece estar ocurriendo en el nivel de caché de plantilla. Este mismo comportamiento se observa independientemente de si las opciones 'Caché de confianza', 'Plantilla de caché en solicitud' o 'Caché de componentes' están marcadas en admin (en cualquier combinación de marcado / no marcado). He borrado el caché de plantilla y el componente de caché más de una vez. Reinicié el servidor CF una y otra vez ... todo fue en vano.

Durante la resolución de problemas, leí este artículo que describe un problema similar con un bloqueo de caché del compilador en CF8 (8.0.1) junto con instrucciones para aplicar un parche para solucionarlo. Pero eso no es CF9 ... así que obviamente no puedo aplicar su parche.

¿Qué hacer? ¿Alguien más ha encontrado este problema? ... ¿Y tienes una solución?

Respuesta 1

Resulta que a veces los archivos de clase están dañados y necesitan ser regenerados. Cuando experimente este problema, se manifestará como se describió anteriormente, con un punto muerto al intentar cargar el archivo de clase dañado. Los pasos para regenerar los archivos de clase son simples, de la siguiente manera:

  1. Vaya al Administrador de ColdFusion> Configuración del servidor> Almacenamiento en caché

  2. Desmarque la siguiente opción:

    [] Guardar archivos de clase Cuando selecciona esta opción, los archivos de clase generados por ColdFusion se guardan en el disco para su reutilización después de que el servidor se reinicia. Adobe recomienda esto para los sistemas de producción. Durante el desarrollo, Adobe recomienda que no seleccione esta opción.

  3. Haga clic en el botón [Enviar cambios]

  4. Reinicie el servidor ColdFusion

  5. Vaya al Administrador de ColdFusion> Configuración del servidor> Almacenamiento en caché

  6. Marque la siguiente opción:

    [x] Guardar archivos de clase Cuando selecciona esta opción, los archivos de clase generados por ColdFusion se guardan en el disco para su reutilización después de que se reinicia el servidor. Adobe recomienda esto para los sistemas de producción. Durante el desarrollo, Adobe recomienda que no seleccione esta opción.

  7. Haga clic en el botón [Enviar cambios]

  8. Y tu hecho! El problema desaparece por completo y todo vuelve a ser como debería ser. ;-)

¿Por qué y cómo se corrompen los archivos de clase? No lo sé. Quizás este podría ser el tema de otra pregunta. Todo lo que sé es que esto resuelve el problema. Por lo general, dudo en aceptar mis propias respuestas como autorizadas, por lo tanto, si alguien más tiene una mejor explicación de este problema y su solución, no dude en publicarlo.

Respuesta: 2

Tengo una clase de Java LayoutManager.java, que paso como un Sprean Bean en mi página jsp usando <custom: useSpringBean var = "layoutManager" bean = "LayoutManager" /> ¿Cómo llamo a los métodos desde ...

Estoy tratando de compilar mis archivos java. Entiendo que usar hormiga en este caso, es la mejor solución. Pero mi proyecto se implementa una sola vez y no lo uso con hormiga. Aprender lo básico sería ...

Actualmente tengo mi aplicación solicitando permisos extendidos para publicar en el muro del usuario al iniciar sesión. ¿Hay alguna manera de hacer que la aplicación solicite estos permisos extendidos no al iniciar sesión pero ...

Siento que estos podrían ser temas básicos, pero no pude encontrarlos respondidos sucintamente en otra parte. Cuando construyo un servidor TCP, entiendo que cada cliente que se conecta tiene que ser cultivado por su cuenta ...