¿Por qué el proceso sigue existiendo después del cierre de Tomcat?
Después del cierre de Tomcat, a menudo se encuentra que todavía hay procesos. Catalina.sh en el directorio Tomcat/bin es un shell de uso común. Generalmente, la operación para abrir y cerrar Tomcat es la siguiente: #. Iniciar tomcat
./catalina.sh?start
#Cerrar tomcat
./catalina.sh?stop
Pero a menudo, Después de desarrollar un proyecto durante un período de tiempo, descubrí que ./catalina.sh stop no puede cerrar Tomcat, pero tengo que usar un comando obligatorio como kill -9
Cuando ./catalina stop no cierra tomat, el amigo que piensa erróneamente que tomcat se ha cerrado correctamente actualizará el código y ./catalina start, por lo que se generan dos tomcats en el servidor. Por ejemplo, el registro es un caos y luego tengo que usar kill -9
De hecho, no es necesario hacer eso. Generalmente, cuando no se puede cerrar, es porque el programador abrió un nuevo hilo en Tomcat y no lo configuró como un demonio, lo que provocó el hilo principal. no poder salir.
¿Cómo saber dónde se inicia el nuevo hilo que no es demonio en el proyecto? De hecho, jdk proporciona la herramienta jstack, que puede ayudarnos a analizar
El método de visualización es muy simple
$JAVA_HOME/bin/ jstack?
pid se refiere al ID del proceso, que se puede ver usando ps -ef|grep tomcat. : [root@localhost?bin]#?ps?-ef|grep?tomcat
root?1513?1?2?23:41?pts/100:00:01?/usr/local/ share/java/jdk1.6.0_25/bin/java?-Djava.util.logging.config .file=/opt/apache-tomcat-6.0.32/conf/logging.properties?-Djava.util.logging.manager= org.apache.juli.ClassLoaderLogManager?-Djava.endorsed.dirs=/opt/apache-tomcat -6.0.32/endorsed?-classpath?/opt/apache-tomcat-6.0.32/bin/bootstrap.jar?-Dcatalina .base=/opt/apache-tomcat-6.0.32?-Dcatalina.home=/opt /apache-tomcat-6.0.32?-Djava.io.tmpdir=/opt/apache-tomcat-6.0.32/temp? org.apache.catalina.startup.Bootstrap?start
root?1544 ?1462?0?23:42?pts/100:00:00?grep?--color=auto?tomcat
El ID del proceso que se ve aquí es 1513
Llamando a jstack View:[root@localhost?bin]#?jstack?1513
2011-07-12?23:44 :00
¿Subproceso completo?Volcado?Java?HotSpot(TM )?Cliente?VM?(20.0-b11?modo?mixto,?compartido):
"Adjuntar?Listener "?daemon?prio=10?tid=0xb41d7c00?nid=0x606?waiting?on? condición?[0x00000000]
java.lang.Thread.State:?RUNNABLE
" TP-Monitor"?daemon?prio=10?tid=0xb41d6400?nid=0x5fa?in ?Object.wait()?[0xb3e0b000]
java.lang.Thread.State:?TIMED_WAITING?(on ?object?monitor)
en?java.lang.Object.wait(¿Nativo?Método)
-?waiting?on?<0x87143720>?(a?org.apache. tomcat.util.threads.ThreadPool$MonitorRunnable)
at?org .apache.tomcat.ut
il.threads.ThreadPool$MonitorRunnable.run(ThreadPool.java:565)
-?locked?<0x87143720>?(a?org.apache.tomcat.util.threads.ThreadPool$MonitorRunnable) p>
at?java.lang.Thread.run(Thread.java:662)
"TP-Processor4"?daemon?prio=10?tid=0xb41d4c00?nid=0x5f9?runnable? [0xb3e5c000]
java.lang.Thread.State:?RUNNABLE
at?java.net.PlainSocketImpl.socketAccept(¿Nativo?Método)
at? java.net.PlainSocketImpl.accept(PlainSocketImpl.java:408)
-?locked?<0x87124770>?(a?java.net.SocksSocketImpl)
en?java.net .ServerSocket.implAccept(ServerSocket.java:462)
at?java.net.ServerSocket.accept(ServerSocket.java:430)
at?org.apache.jk.common .ChannelSocket.accept(ChannelSocket.java:311)
at?org.apache.jk.common.ChannelSocket.acceptConnections(ChannelSocket.java:668)
at?org.apache .jk.common.ChannelSocket$SocketAcceptor.runIt(ChannelSocket.java:879)
at?org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:690) p> p>
at?java.lang.Thread.run(Thread.java:662)
Consulte el demonio "Adjuntar escucha" prio=10 tid=0xb41d7c00 nid=0x606 esperando en condición [0x00000000 ]
java.lang.Thread.State: RUNNABLE
En esta línea, el primer "Adjuntar escucha" es el nombre del hilo y el siguiente demonio es el estado del demonio del hilo <. /p>
El hilo principal no es un demonio, por lo que es así:
"main"?prio=10?tid=0xb6d05000?nid=0x5ea?runnable?[0xb6ee9000]
java.lang.Thread.State:?RUNNABLE
en?java.net.PlainSocketImpl.socketAccept(Native?Method)
en?java.net.PlainSocketImpl. aceptar (PlainSocketImpl.java:408)<
/p>
-?bloqueado?<0x871644a8>?(a?java.net.SocksSocketImpl)
en?java.net.ServerSocket.implAccept(ServerSocket.java:462)
en?java.net.ServerSocket.accept(ServerSocket.java:430)
en?org.apache.catalina.core.StandardServer.await(StandardServer.java:431)
at?org.apache.catalina.startup.Catalina.await(Catalina.java:676)
at?org.apache.catalina.startup.Catalina.start(Catalina.java:628)
at?sun.reflect.NativeMethodAccessorImpl.invoke0(Native?Method)
at?sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
en?sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
en?java.lang.reflect.Method.invoke(Method.java:597)
en ?org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289)
en?org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)
No hay ningún demonio después de "main". Cuando veas el estado de este hilo, sigue las pistas y encuentra el lugar correspondiente al nuevo hilo SetDaemon(true). /catalina se detiene felizmente.