生产环境-linux-catalina.sh脚本停止不了服务分析解决推荐

在生产测试环境中,在使用脚本catalina.sh停止tomcat进程后失败,即时在catalina.sh脚本执行时加入-force参数也会失败,使用sh -x 分析catalina.sh脚本停止过程,将停止失败的地方抽取出来:

+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/temporg.apache.catalina.startup.Bootstrapstop2015-3-2111:59:53org.apache.catalina.startup.CatalinastopServer严重:Catalina.stop:java.net.ConnectException:Connectionrefusedatjava.net.PlainSocketImpl.socketConnect(NativeMethod)atjava.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351)atjava.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213)atjava.net.PlainSocketImpl.connect(PlainSocketImpl.java:200)atjava.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)atjava.net.Socket.connect(Socket.java:529)atjava.net.Socket.connect(Socket.java:478)atjava.net.Socket. init (Socket.java:375)atjava.net.Socket. init (Socket.java:189)atorg.apache.catalina.startup.Catalina.stopServer(Catalina.java:422)atsun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethod)atsun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)atsun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)atjava.lang.reflect.Method.invoke(Method.java:597)atorg.apache.catalina.startup.Bootstrap.stopServer(Bootstrap.java:338)atorg.apache.catalina.startup.Bootstrap.main(Bootstrap.java:416)+'[''!'-z''']'+'['1-eq1']'+'['-z''']'+echo'Killfailed:$CATALINA_PIDnotset'Killfailed:$CATALINA_PIDnotset

从中可以看到,首先是执行java命令失败,没有停止tomcat,然后执行-force模块的命令,但是却没有找到$CATALINA_PID设定的进程号,我们先不去关注java执行stop命令为什么报错,而是看看为什么加了-force参数也不起作用了

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

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

第一处:

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

$CATALINA_PID",如果存在则不显示if[!-z"$CATALINA_PID"];thenecho"UsingCATALINA_PID:$CATALINA_PID"fifi

#貌似只是判断$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 #从 可以看出启动的命令在后台启动fiif[!-z"$CATALINA_PID"];then#判断CATALINA_PID如果不是空字符,则将Shell最后运行的后台Process的PID传给$CATALINA_PIDecho$! "$CATALINA_PID"#在使用命令运行进程至后台时,可以使用$!抓取前面启动运行在后台进程的进程号#上面语句是tomcat在启动时,会将$CATALINA_PID写入PID进程号

第三处:

#一下语句都出现在stop模块内if[!-z"$CATALINA_PID"];then#$CATALINA_PID文件不是非空if[-f"$CATALINA_PID"];thenif[-s"$CATALINA_PID"];thenkill-0`cat"$CATALINA_PID"` /dev/null2 1#kill-0pid不发送任何信号,但是系统会进行错误检查。if[$?-gt0];thenecho"PIDfilefoundbutnomatchingprocesswasfound.Stopaborted."exit1fielseecho"PIDfileisemptyandhasbeenignored."fielseecho"\$CATALINA_PIDwassetbutthespecifiedfiledoesnotexist.IsTomcatrunning?Stopaborted."exit1fifi

#如果发现$CATALINA_PID则发送一个模拟结束进程的型号,如果返回值为0,则正常,其他则异常,做退出操作

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

第四处:

#下面的代码紧接着stop的正常停止代码下if[!-z"$CATALINA_PID"];then#如果$CATALINA_PID不为空if[-f"$CATALINA_PID"];then#而且还是普通文件while[$SLEEP-ge0];do#而且$SLEEP还大于0kill-0`cat"$CATALINA_PID"` /dev/null2 1#则测试下tomcat能不能被关闭if[$?-gt0];then#剩下的参数还有,则清空$CATALINA_PIDrm-f"$CATALINA_PID" /dev/null2 1if[$?!=0];thenif[-w"$CATALINA_PID"];thencat/dev/null "$CATALINA_PID"elseecho"TomcatstoppedbutthePIDfilecouldnotberemovedorcleared."fifibreakfiif[$SLEEP-gt0];thensleep1fiif[$SLEEP-eq0];thenif[$FORCE-eq0];thenecho"Tomcatdidnotstopintime.PIDfilewasnotremoved."fifiSLEEP=`expr$SLEEP-1`donefifi#上段语句主要是判断tomcat是否被关闭#核心语句还是:kill-0`cat"$CATALINA_PID"` /dev/null2 1#while语句做sleep使用,用于清空$CATALINA_PID#但是[!-z"$CATALINA_PID"]导致这段语句什么都没做啊!!!!!

第五处:

#这段代码就是涉及-force的核心代码了if[$FORCE-eq1];thenif[-z"$CATALINA_PID"];thenecho"Killfailed:\$CATALINA_PIDnotset"elseif[-f"$CATALINA_PID"];thenPID=`cat"$CATALINA_PID"`echo"KillingTomcatwiththePID:$PID"kill-9$PID#强制执行的核心命令rm-f"$CATALINA_PID" /dev/null2 1if[$?!=0];thenecho"TomcatwaskilledbutthePIDfilecouldnotberemoved."fifififi#从中就可以看出,sh-x输出的Killfailed:$CATALINA_PIDnotset是怎么来的

总结下,$CATALINA_PID在整个代码中的作用:

1.在tomcat启动时会写入$CATALINA_PID,但是假设我们的环境是多tomcat项目或$CATALINA_PID为空

2.stop代码中,检查$CATALINA_PID是否为空字符,是的话什么都不做

3.sstop代码中,检查$CATALINA_PID是否为空字符,是的话什么都不做

4.force代码中,检查$CATALINA_PID是否为空字符,是的话就报错

也就是说只要没有保存中这个项目的PID,那么正常stop停止不了,-force也是没有用的。

那么该如何解决呢?直接给$CATALINA_PID付PID的值,那么看结果:

+FORCE=1+'[''!'-z12031']'+'['-f12031']'+echo'$CATALINA_PIDwassetbutthespecifiedfiledoesnotexist.IsTomcatrunning?Stopaborted.'$CATALINA_PIDwassetbutthespecifiedfiledoesnotexist.IsTomcatrunning?Stopaborted.

涉及到的代码:

if[-f"$CATALINA_PID"];thenif[-s"$CATALINA_PID"];thenkill-0`cat"$CATALINA_PID"` /dev/null2 1#kill-0pid不发送任何信号,但是系统会进行错误检查。if[$?-gt0];thenecho"PIDfilefoundbutnomatchingprocesswasfound.Stopaborted."exit1elseecho"PIDfileisemptyandhasbeenignored."fiecho"\$CATALINA_PIDwassetbutthespecifiedfiledoesnotexist.IsTomcatrunning?Stopaborted."exit1#$CATALINA_PID不是个文件,所以不好意思,我退出了....

原来$CATALINA_PID还必须是个文件,那么我们可不可以建这么一个文件呢?

在catalina.sh脚本的代码前,加入以下语句:

CATALINA_PID=/home/xrltest1/tomcat/CATALINA_PIDecho12031 $CATALINA_PID

结果:tomcat停止执行成功,完成结束进程任务

总结:

在我看到的很到部署tomcat的文章中,还没发现有关于设置$CATALINA_PID文件路径的提示(也许是我看到的少),但是此处我要建议小伙伴们,在写tomcat启动、停止、重启的脚本的时候,一定要注意这个变量。

我们可以看出,整个代码中,隐含的一个信息,$CATALINA_PID既要是一个文件还要写入tomcat项目的PID,那么catalina.sh在停止时,则会一路畅通…

需要我们注意的是tomcat在启动时,同样的参数会启动多个实例,这个是我们不想看到了,所以tomcat启动、停止、重启还需要编写脚本,至于如何编写出满意的脚本,作者将在后面的文章中将作者在生产中使用的脚本举列给各位小伙伴分析下~

即使没有收获的希望也心平气和的继续。

生产环境-linux-catalina.sh脚本停止不了服务分析解决推荐

相关文章:

你感兴趣的文章:

标签云: