Tomcat doesn't stop. How can I debug this?

后端 未结 7 739
旧时难觅i
旧时难觅i 2020-12-03 06:29

I have a Tomcat 7 running in Linux that I start via $CATALINA_HOME/bin/startup.sh and shutdown via $CATALINA_HOME/bin/shutdown.sh

相关标签:
7条回答
  • 2020-12-03 07:07

    In my case I had one rogue JPA EntityManager that wasn't being properly closed after use. Fixed that, and now I can Clean-and-Build again without killing the damn Java process everytime :)

    0 讨论(0)
  • 2020-12-03 07:13

    Check if your Web Application has some Scheduler active, like Quartz.

    If you don't stop it, Web Application Thread never ending until you kill it

    0 讨论(0)
  • 2020-12-03 07:15

    I had the exact same problem. Sometimes, the command ./shutdown.sh does not stop the tomcat process, and its java process stays in the running processes.

    I had solved this problem using the Tomcat version in the Ubuntu's software repositories, by:

    sudo apt-get install tomcat7
    

    After installing it from package manager and configuring some settings, I did not have any problems on stopping/starting Tomcat. I used this command to stop, and it never failed:

    service tomcat7 stop
    

    which is nearly the same as

    /etc/init.d/tomcat7 stop
    

    Using this command runs the code block from the init script, specifically, the codes from the file /etc/init.d/tomcat7. So I looked into it to see what it does to always kill the tomcat process succesfully. Here is the code block that runs when you use service tomcat7 stop command:

    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
            ;;
    

    The important part is this:

    start-stop-daemon --stop --pidfile "$CATALINA_PID" \
                                --user "$TOMCAT7_USER" \
                                --retry=TERM/20/KILL/5 >/dev/null
    

    This means "retry stopping until the process is stopped. Here is the --retry command documentation from start-stop-daemon manual:

       -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.
              ...
    

    So, --retry=TERM/20/KILL/5 means "Send TERM signal to the process, wait 20 seconds, if it's still running, send KILL signal, wait 5 seconds, if it's still running, there is a problem.

    This means you can configure the tomcat to run as a deamon and use a command like this, or write a script to do that kind of action to stop tomcat, or just use Ubuntu and get the tomcat from the package manager.

    0 讨论(0)
  • 2020-12-03 07:18

    If the web application is stopped, all connections to the database should be closed as well. If you don't have a list of connections, then execute the SQL statement "shutdown" (this only works for the H2 and HSQLDB databases).

    If you have a registered a Servlet, you can do that in the Servlet.destroy() method.

    If you have registered a ServletContextListener, you can execute the "shutdown" statement in the ServletContextListener.contextDestroyed(ServletContextEvent servletContextEvent) method. This is what org.h2.server.web.DbStarter ServletContextListener does (the one that is included in the H2 database).

    0 讨论(0)
  • 2020-12-03 07:18

    I also had the same problem. There was a ThrottledThreadPoolExecutor in my application that wasn't getting shutdown. When I shut it down properly, tomcat would stop cleanly. In order to figure out the problem, I had to remove all the apps from my tomcat webapps directory and then add them one by one and see which one was causing the problem

    0 讨论(0)
  • 2020-12-03 07:18

    If you're using a Scheduler or some other entity in your web app, you need to shut it down. Typically you have to use a ServletContextListener to provide the hook to make your shutdown call. A shutdown hook won't work in this case because the JVM is not shutting down (yet). Believe me, I've tried. If your code is in agent code or something outside the container/webapp, then a shutdown hook SHOULD work, though often it's a hair pulling experience to figure out why it's STILL not working. Note, I'm bald.

    0 讨论(0)
提交回复
热议问题