Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Tomcat没有';不要停下来。我如何调试这个?_Java_Linux_Multithreading_Tomcat_H2 - Fatal编程技术网

Java Tomcat没有';不要停下来。我如何调试这个?

Java Tomcat没有';不要停下来。我如何调试这个?,java,linux,multithreading,tomcat,h2,Java,Linux,Multithreading,Tomcat,H2,我有一个运行在Linux中的Tomcat 7,通过$CATALINA_HOME/bin/startup.sh启动,通过$CATALINA_HOME/bin/shutdown.sh关闭 从/etc/init.d 除了一个问题外,一切正常。有时候tomcat不会停下来。 虽然我停止了它,并且在catalina.out日志中看到了正在下降的情况,但是如果我执行ps-ef操作,我仍然可以看到进程正在运行 有什么问题吗?我如何调试这个?我的感觉是,这与线程有关 因此,可疑的部分如下: 1) 我使用Log4

我有一个运行在Linux中的Tomcat 7,通过
$CATALINA_HOME/bin/startup.sh启动,通过
$CATALINA_HOME/bin/shutdown.sh关闭
从
/etc/init.d

除了一个问题外,一切正常。有时候tomcat不会停下来。
虽然我停止了它,并且在catalina.out日志中看到了正在下降的情况,但是如果我执行
ps-ef
操作,我仍然可以看到进程正在运行

有什么问题吗?我如何调试这个?我的感觉是,这与线程有关

因此,可疑的部分如下:
1) 我使用Log4j的LogManager来检测Log4j配置是否已更改,但我在
contextdestromed
ServletContextListener上执行
Log4jManager.shutdown
2) 我使用
H2
数据库,在关机时看到:

严重:web应用程序[/MyApplication]似乎已启动一个
名为[H2 Log Writer MYAPPLICATION]的线程,但未能停止该线程。
这很可能会造成内存泄漏

严重:web应用程序[/MyApplication]似乎已启动一个
名为[H2 File Lock Watchdog]的线程
/opt/myOrg/tomcat/webapps/MyApplication/db/myDatabase.lock.db]但有
没能阻止它。这很可能会造成内存泄漏。4月2日,
2012年9:08:08 AM org.apache.catalina.loader.WebappClassLoader
clearReferencesThreads严重:web应用程序[/MyApplication]
似乎已启动名为[FileWatchdog]的线程,但已失败
阻止它。这很可能会造成内存泄漏

需要帮忙吗?我如何在这里发现问题

更新:
按照@daveb的建议,我做了一个
kill-3
,在catalina.out中我看到:

JVMDUMP006I正在处理转储事件“用户”,详细信息“”-请稍候。 JVMDUMP032I JVM使用请求的Java转储 “/etc/init.d/javacore.20120402.093922.2568.0001.txt”以响应 事件JVMDUMP010I Java转储写入 /etc/init.d/javacore.20120402.093922.2568.0001.txt JVMDUMP013I 已处理转储事件“用户”,详细信息“”


/etc/init.d
中有一个javacore,但我不知道如何处理它。也就是说,我应该调查哪些部分

通过使用jstack或向进程发送信号,找出哪些线程仍在运行(或被阻止,等待运行):

kill -3 pid
当您知道这一点时,您可以将启动线程的任何内容挂接到关机通知中,以停止线程。或者让那些线程成为执事线程

有关此操作的更多详细信息,请参阅


如果你不知道你的线程是在哪里创建的,那么考虑给它们添加名字——执行器可以使用线程工厂,并且你可以使用这些工厂来设置线程的DeAMon状态,也可以命名它——这样你的堆栈跟踪会更加清晰。与数据库的所有连接也应关闭。如果没有连接列表,则执行SQL语句“shutdown”(这仅适用于H2和HSQLDB数据库)

如果您注册了一个Servlet,那么可以在
Servlet.destroy()
方法中执行此操作


如果已注册了
ServletContextListener
,则可以在
ServletContextListener.contextdestromed(ServletContextEvent ServletContextEvent)
方法中执行“shutdown”语句。这就是
org.h2.server.web.DbStarter
ServletContextListener
所做的(h2数据库中包含的一个)。

我遇到了完全相同的问题。有时,命令
/shutdown.sh
不会停止tomcat进程,而它的
java
进程会停留在正在运行的进程中

我使用Ubuntu软件库中的Tomcat版本解决了这个问题,方法是:

sudo apt-get install tomcat7
从PackageManager安装并配置一些设置后,我在停止/启动Tomcat时没有遇到任何问题。我使用此命令停止,但从未失败:

service tomcat7 stop
这几乎和

/etc/init.d/tomcat7 stop
使用此命令运行init脚本中的代码块,特别是文件
/etc/init.d/tomcat7
中的代码。所以我研究了一下它,看看它能做些什么来成功地终止tomcat进程。以下是使用
service tomcat7 stop
命令时运行的代码块:

log_daemon_msg "Stopping $DESC" "$NAME"

        set +e
        if [ -f "$CATALINA_PID" ]; then
                start-stop-daemon --stop --pidfile "$CATALINA_PID" \
                        --user "$TOMCAT7_USER" \
                        --retry=TERM/20/KILL/5 >/dev/null
                if [ $? -eq 1 ]; then
                        log_progress_msg "$DESC is not running but pid file exists, cleaning up"
                elif [ $? -eq 3 ]; then
                        PID="`cat $CATALINA_PID`"
                        log_failure_msg "Failed to stop $NAME (pid $PID)"
                        exit 1
                fi
                rm -f "$CATALINA_PID"
                rm -rf "$JVM_TMP"
        else
                log_progress_msg "(not running)"
        fi
        log_end_msg 0
        set -e
        ;;
重要的是:

start-stop-daemon --stop --pidfile "$CATALINA_PID" \
                            --user "$TOMCAT7_USER" \
                            --retry=TERM/20/KILL/5 >/dev/null
这意味着“重试停止,直到进程停止。以下是启动-停止守护程序手册中的--retry命令文档:

因此,
--retry=TERM/20/KILL/5
表示“向进程发送TERM信号,等待20秒,如果进程仍在运行,则发送KILL信号,等待5秒,如果进程仍在运行,则出现问题


这意味着您可以将tomcat配置为作为deamon运行,并使用类似的命令,或者编写脚本来执行此类操作以停止tomcat,或者仅使用Ubuntu并从包管理器获取tomcat。

检查您的Web应用程序是否有一些调度程序处于活动状态,如Quartz


如果您不停止它,Web应用程序线程将永远不会结束,直到您杀死它。

在我的例子中,我有一个恶意的JPA EntityManager,在使用后没有正确关闭。修复了这个问题,现在我可以在每次不杀死该死的Java进程的情况下再次清理和构建:)

我也遇到了同样的问题。我的应用程序中有一个ThrottledThreadPoolExecutor没有关闭。当我正确地关闭它时,tomcat会完全停止。为了找出问题所在,我必须从我的tomcat
webapps
目录中删除所有应用程序,然后逐个添加它们,看看是哪一个导致了问题

如果您在web应用程序中使用调度程序或其他实体,则需要将其关闭。通常,您必须使用ServletContextListener提供钩子来进行关闭调用。
   -R|--retry timeout|schedule
          With  --stop,  specifies  that  start-stop-daemon  is  to  check
          whether  the  process(es)  do  finish.  It will check repeatedly
          whether any matching processes are running, until none are.   If
          the  processes  do  not exit it will then take further action as
          determined by the schedule.

          If timeout is specified instead of schedule  then  the  schedule
          signal/timeout/KILL/timeout  is used, where signal is the signal
          specified with --signal.
          ...