技术标签: 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/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.(Socket.java:375)
at java.net.Socket.(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 "[email protected]" 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变量没有设定,所以这个判断直接就结束了,什么都没做
第四处:#下面的代码紧接着stop的正常停止代码下
if [ ! -z "$CATALINA_PID" ]; then
#如果$CATALINA_PID不为空
if [ -f "$CATALINA_PID" ]; then
#而且还是普通文件
while [ $SLEEP -ge 0 ]; do
#而且$SLEEP还大于0
kill -0 `cat "$CATALINA_PID"` >/dev/null 2>&1
#则测试下tomcat能不能被关闭
if [ $? -gt 0 ]; then
#剩下的参数还有,则清空$CATALINA_PID
rm -f "$CATALINA_PID" >/dev/null 2>&1
if [ $? != 0 ]; then
if [ -w "$CATALINA_PID" ]; then
cat /dev/null > "$CATALINA_PID"
else
echo "Tomcat stopped but the PID file could not be removed or cleared."
fi
fi
break
fi
if [ $SLEEP -gt 0 ]; then
sleep 1
fi
if [ $SLEEP -eq 0 ]; then
if [ $FORCE -eq 0 ]; then
echo "Tomcat did not stop in time. PID file was not removed."
fi
fi
SLEEP=`expr $SLEEP - 1 `
done
fi
fi
#上段语句主要是判断tomcat是否被关闭
#核心语句还是:kill -0 `cat "$CATALINA_PID"` >/dev/null 2>&1
#while语句做sleep使用,用于清空$CATALINA_PID
#但是[ ! -z "$CATALINA_PID" ]导致这段语句什么都没做啊!!!!!
第五处:#这段代码就是涉及-force的核心代码了
if [ $FORCE -eq 1 ]; then
if [ -z "$CATALINA_PID" ]; then
echo "Kill failed: \$CATALINA_PID not set"
else
if [ -f "$CATALINA_PID" ]; then
PID=`cat "$CATALINA_PID"`
echo "Killing Tomcat with the PID: $PID"
kill -9 $PID
#强制执行的核心命令
rm -f "$CATALINA_PID" >/dev/null 2>&1
if [ $? != 0 ]; then
echo "Tomcat was killed but the PID file could not be removed."
fi
fi
fi
fi
#从中就可以看出,sh -x输出的Kill failed: $CATALINA_PID not set是怎么来的
总结下,$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
+ '[' '!' -z 12031 ']'
+ '[' -f 12031 ']'
+ echo '$CATALINA_PID was set but the specified file does not exist. Is Tomcat running? Stop aborted.'
$CATALINA_PID was set but the specified file does not exist. Is Tomcat running? Stop aborted.
涉及到的代码: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
#$CATALINA_PID不是个文件,所以不好意思,我退出了....
原来$CATALINA_PID还必须是个文件,那么我们可不可以建这么一个文件呢?
在catalina.sh脚本的代码前,加入以下语句:CATALINA_PID=/home/xrltest1/tomcat/CATALINA_PID
echo 12031 > $CATALINA_PID
结果:tomcat停止执行成功,完成结束进程任务
总结:
在我看到的很到部署tomcat的文章中,还没发现有关于设置$CATALINA_PID文件路径的提示(也许是我看到的少),但是此处我要建议小伙伴们,在写tomcat启动、停止、重启的脚本的时候,一定要注意这个变量。
我们可以看出,整个代码中,隐含的一个信息,$CATALINA_PID既要是一个文件还要写入tomcat项目的PID,那么catalina.sh在停止时,则会一路畅通...
需要我们注意的是tomcat在启动时,同样的参数会启动多个实例,这个是我们不想看到了,所以tomcat启动、停止、重启还需要编写脚本,至于如何编写出满意的脚本,作者将在后面的文章中将作者在生产中使用的脚本举列给各位小伙伴分析下~
SYN flood攻击原理利用TCP三次握手的过程漏洞 大量发送第一次握手(假IP)的报文 攻击方忽略第二次握手的报文 被攻击方多个TCP连接处于同步已被接收阶段(SYNC-RCVD),耗费大量资源 最终因为资源耗尽,拒绝服务(DoS)资源耗尽类攻击:攻击方控制大量“肉鸡”(大量被黑客控制的计算机) 向攻击目标发送大量连接握手报文 完成三次握手后保持连接,但不做任何事情,消耗TCP连接资源 或者马上断开连接有重新发起连接 服务器不堪重负,最终影响正常服务或直接宕机协议特性
系统定时任务及延时任务一、系统延时任务(at)1.基础内容2.at任务的黑白名单二、系统定时任务1.crontab 时间表示方式2.系统控制crontab的服务3.crontab指令4.系统级别的cron(文件方式设定定时任务)5.crontab的黑白名单三、系统中临时文件的管理方式一、系统延时任务(at)1.基础内容[[email protected] ~]# at 23:37 ##设定任务执行时间at> rm -fr /mnt/* ##任务动作at> <EOT><
Description在一个凹槽中放置了 n 层砖块、最上面的一层有n 块砖,从上到下每层依次减少一块砖。每块砖都有一个分值,敲掉这块砖就能得到相应的分值,如下图所示。14 15 4 3 23 33 33 76 2 2 13 11 22 23 31如果你想敲掉第 i 层的第j 块砖的话,若i=1,你可以直接敲掉它;若i...
下面我们来看看libgdx游戏引擎中一些常用的类1.Gdx类 Gdx是Libgdx类库运行的核心所在,不单运行Graphics、Input、Files、Audio、AndroidApplication等Libgdx关键部分,所必需的实例会在Libgdx初始化时注入Gdx中对应的graphics、input、files、audio、app等静态变量里面,就连Li...
一、搭建SpringBoot项目1.1、file ——> new ——> project——> Spring Initializr——> next——> next——> next——> finish注意选择包依赖关系二、springboot整合mybatis.mysql2.1、整体结构2.2、设置所需要的依赖即pom.xml文件xsi:schemaLoca...
windowSoftInputMode属性详解首先,我们从这个属性的名称中,可以很直观的看出它的作用,这个属性就是来设置窗口软键盘的交互模式的。 android:windowSoftInputMode属性一共有10个取值,分别是:stateUnspecified,stateUnchanged,stateHidden,stateAlwaysHidden,stateVisible,stateAlwaysVisible,adjustUnspecified,adjustResize,adjustP...
errno错误对照表:errno0 : Successerrno1 : Operation not permittederrno2 : No such file or directoryerrno3 : No such processerrno4 : Interrupted system callerrno5 ...
MyBatis动态标签MyBatis9种动态标签动态标签用法1.if2.choose、when、otherwise3.where4.set5.trim6.foreach7.bindMyBatis9种动态标签MyBatis提供了9种动态SQL标签:trim、where、set、foreach、if、choose、when、otherwise、bind;其执行原理为,使用OGNL从SQL参数对象中计算表达式的值,根据表达式的值动态拼接SQL,以此来完成动态SQL的功能。动态标签用法1.ifIf :
21.Schema.xml和solrconfig.xml配置文件里參数说明: 參考资料:http://www.hipony.com/post-610.html 22.执行时报错: 23., /commons-cloud/src/main/resources/testClientUtil.properties 中配置的什么? 在ws-cloud中也有个 答...
Win7 win8 win8.1安装.msi程序时出现2502、2503错误解决办法(zend studio.msi 安装汉化为例)时间:2014-11-07 19:11:38 阅读:2172 评论:0 收藏:0[点我收藏+]标签:安装.msi程序时出现2502、2503错误解决办法 zend studio.msi 安装汉化为例...
文章目录概述1.es中的基础概念2.es中的索引过程2.1 一次index请求的大体流程2.2 为什么是near real time2.3 为什么要有translog2.3.1 translog的作用2.3.2 translog的持久化机制2.3.2 commit产生的时机概述 这里主要讲讲es index的过程,努力揭示es在index过程中具体做了哪些工作。从而增加我们对es的了解,以便于更好的使用和优化es。1.es中的基础概念es的基础支撑是使用lucene,每个es的索引(index
选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是:第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零。选择排序是不稳定的排序方法。 选择排序就是从当前未排序的整数中找一个最小的整数,将它放在已排序的整数列表的最后。 要点: 比较相邻的两个数,如果左边的数大于右边的数,就进行交换。 例如: 将数组 { 4,2,8,0