Linux中Tomcat shutdown.sh后进程仍然存在解决办法

最近我们在使用Jenkins自动化部署项目时,在生产liunx环境下,使用脚本shutdown.sh停止tomcat服务,然后再start之后发现应用无法访问了,后台查看tomcat进程是发现有个2个tomcat进程,说明之前的shutdown并没有完全停掉tomcat进程。那怎么样tomcat使用shutdown之后立马关掉其进程呢? 经查资料发现在shutdown.sh脚本之后有条命令是这样的:

exec "$PRGDIR"/"$EXECUTABLE" stop "$@"这个就是停止tomcat 服务的命令,我们只需要加一个  -force  就可以在shutdown时强制关闭tomcat进程

exec "$PRGDIR"/"$EXECUTABLE" stop -force "$@"

但光这样还是不行,再shutdown时报错:

Kill failed: $CATALINA_PID not set查找失败原因:

+ FORCE=1
+ '[' '!' -z '' ']'
+ /usr/java/jdk1.6.0_38/bin/java -server -Xms2048m -Xmx2048m -Xmn768m -XX:PermSize=128m -XX:MaxPermSize=256m -XX:+UseParallelOldGC -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/xrltest1/tomcat/dumpfile/heap.bin -Xloggc:/home/xrltest1/tomcat/logs/gc.log -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs=/home/xrltest1/tomcat/endorsed -classpath /home/xrltest1/tomcat/bin/bootstrap.jar -Dcatalina.base=/home/xrltest1/tomcat -Dcatalina.home=/home/xrltest1/tomcat -Djava.io.tmpdir=/home/xrltest1/tomcat/temp org.apache.catalina.startup.Bootstrap stop
2015-3-21 11:59:53 org.apache.catalina.startup.Catalina stopServer
严重: Catalina.stop:
java.net.ConnectException: Connection refused
  at java.net.PlainSocketImpl.socketConnect(Native Method)
  at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351)
  at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213)
  at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:200)
  at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
  at java.net.Socket.connect(Socket.java:529)
  at java.net.Socket.connect(Socket.java:478)
  at java.net.Socket.<init>(Socket.java:375)
  at java.net.Socket.<init>(Socket.java:189)
  at org.apache.catalina.startup.Catalina.stopServer(Catalina.java:422)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
  at java.lang.reflect.Method.invoke(Method.java:597)
  at org.apache.catalina.startup.Bootstrap.stopServer(Bootstrap.java:338)
  at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:416)
+ '[' '!' -z '' ']'
+ '[' 1 -eq 1 ']'
+ '[' -z '' ']'
+ echo 'Kill failed: $CATALINA_PID not set'
Kill failed: $CATALINA_PID not set
从中可以看到,首先是执行java命令失败,没有停止tomcat,然后执行-force模块的命令,但是却没有找到$CATALINA_PID设定的进程号,我们先不去关注java执行stop命令为什么报错,而是看看为什么加了-force参数也不起作用了

为什么没有$CATALINA_PID?接下来就带大家一探究竟

首先,我们将涉及到$CATALINA_PID变量的代码全部提取出来:

第一处:

#以下这句判断设置的$CATALINA_PID变量如果不存在,则显示"Using CATALINA_PID:

$CATALINA_PID",如果存在则不显示
  if [ ! -z "$CATALINA_PID" ]; then
    echo "Using CATALINA_PID:    $CATALINA_PID"
  fi
fi#貌似只是判断$CATALINA_PID是否是空字符,其他什么都没有做

第二处:(涉及到start参数的模块内的$CATALINA_PID变量,只是提出来分析,其实不对stop模块有影响)

#这个是start模块内的代码
"$_RUNJAVA" "$LOGGING_CONFIG" $JAVA_OPTS $CATALINA_OPTS \
  -Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath "$CLASSPATH" \
  -Dcatalina.base="$CATALINA_BASE" \
  -Dcatalina.home="$CATALINA_HOME" \
  -Djava.io.tmpdir="$CATALINA_TMPDIR" \
  org.apache.catalina.startup.Bootstrap "$@" start \
  >> "$CATALINA_OUT" 2>&1 &
#从&可以看出启动的命令在后台启动
  fi
if [ ! -z "$CATALINA_PID" ]; then
#判断CATALINA_PID如果不是空字符,则将Shell最后运行的后台Process的PID 传给$CATALINA_PID
echo $! > "$CATALINA_PID"
#在使用命令运行进程至后台时,可以使用$!抓取前面启动运行在后台进程的进程号
fi
fi
#上面语句是tomcat在启动时,会将$CATALINA_PID写入PID进程号第三处:

#一下语句都出现在stop模块内
if [ ! -z "$CATALINA_PID" ]; then
#$CATALINA_PID文件不是非空
  if [ -f "$CATALINA_PID" ]; then
    if [ -s "$CATALINA_PID" ]; then
      kill -0 `cat "$CATALINA_PID"` >/dev/null 2>&1
#kill -0 pid 不发送任何信号,但是系统会进行错误检查。
      if [ $? -gt 0 ]; then
        echo "PID file found but no matching process was found. Stop aborted."
        exit 1
      fi
    else
      echo "PID file is empty and has been ignored."
    fi
  else
    echo "\$CATALINA_PID was set but the specified file does not exist. Is Tomcat running? Stop aborted."
    exit 1
  fi
fi
#如果发现$CATALINA_PID则发送一个模拟结束进程的型号,如果返回值为0,则正常,其他则异常,做退出操作

#从上面的sh -x输出的信息对应的是:'[' '!' -z '' ']' 可以看出$CATALINA_PID变量没有设定,所以这个判断直接就结束了,什么都没做

第四处:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/fea9cd08f33f63d542eb22d8b76ee000.html