关于linux下shutdown关闭不掉tomcat问题的解决办法

关于linux下shutdown关闭不掉tomcat问题的解决办法

Oops~  今天写下今天遇到的问题,相信众位程序员一定也有遇到的--linux下shutdown关闭不掉tomcat问题。

首先描述下遇到的情况。当多次启动tomcat后,发现在系统下有类似于这样的日志文件或者输入任何命令都会抛出一堆balabala的东西,打开日志会发现报告内存不足等乱七八糟的东西(造成的原因有不少,其中内存不够用应该是大多数遇到的情况),输入free -m 后,如果你发现是内存不够用了,当然这时候你可能还不知道是因为tomcat未关闭造成的原因,你会一个一个排查,然并卵。如果你的机子上有运行过或正在运行的tomcat,那么不妨输入ps -ef|grep tomcat,你可能会发现有N个未关闭 的tomcat进程,ok一个一个kill掉就好,那么接下来的问题又来了,每次都手动kill掉会很不爽,接下来就是本文要解决的问题了。上面说了一堆废话,O(∩_∩)O哈哈哈~,不爽请喷。

解决问题的办法:

方法一:从tomcat下项目入手,一般造成这种原因是因为项目中有非守护线程的存在。那么怎么找到改线程呢,请看下面:

利用jdk 提供的jstack可以帮助我们找到:
$JAVA_HOME/bin/jstack  <pid>
pid是指进程ID, 用ps -ef|grep tomcat 就可以查看到:

12126即为pid,继续输入jstack 12126会看到如下一堆balabala的东西:

上面最前变的"Attach Listener" 是线程名, 紧跟其后的 daemon是线程的守护状态,

你可能会遇到下面的状况(俺遇到的不是,下面的状况是从别人那转过来的)

 

其中主线程不是daemon的,所以是这样:

 

"main" prio=10 tid=0xb6d05000 nid=0x5ea runnable [0xb6ee9000]

   java.lang.Thread.State: RUNNABLE

        at java.net.PlainSocketImpl.socketAccept(Native Method)

        at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:408)

        - locked <0x871644a8> (a java.net.SocksSocketImpl)

        at java.net.ServerSocket.implAccept(ServerSocket.java:462)

        at java.net.ServerSocket.accept(ServerSocket.java:430)

        at org.apache.catalina.core.StandardServer.await(StandardServer.java:431)

        at org.apache.catalina.startup.Catalina.await(Catalina.java:676)

        at org.apache.catalina.startup.Catalina.start(Catalina.java:628)

        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.start(Bootstrap.java:289)

        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)

在"main" 后没有daemon,看到这样的线程状态,顺藤摸瓜,找到对应new Thread的地方setDaemon(true)就可以,痛痛快快的shutdown了:

你也可能会看到类似下面的状况(我遇到的就是这种情况大哭):

如果你看到类似于"DestroyJavaVM" prio=10 balabala的东西,那么恭喜你,你的程序可能出现了死锁,关于死锁方面的资料可以看着这篇文章点击打开链接看下,这里就不多做介绍了。继续往下看如果发现有waiting on condition等字样说明你的程序如果发现有大量的线程都在处在 Wait on condition,从线程 stack看, 正等待网络读写,这可能是一个网络瓶颈的征兆。因为网络阻塞导致线程无法执行。一种情况是网络非常忙,几乎消耗了所有的带宽,仍然有大量数据等待网络读写;另一种情况也可能是网络空闲,但由于路由等问题,导致包无法正常的到达。所以要结合系统的一些性能观察工具来综合分析,比如 netstat统计单位时间的发送包的数目,如果很明显超过了所在网络带宽的限制 ; 观察 cpu的利用率,如果系统态的 CPU时间,相对于用户态的 CPU时间比例较高;如果程序运行在 Solaris 10平台上,可以用 dtrace工具看系统调用的情况,如果观察到 read/write的系统调用的次数或者运行时间遥遥领先;这些都指向由于网络带宽所限导致的网络瓶颈。另外一种出现 Wait on condition的常见情况是该线程在 sleep,等待 sleep的时间到了时候,将被唤醒。 前面蓝色字体是度娘百出来的结果。详细请点击打开链接。好既然已找到问题所在了,那么接下来就叫给你自己解决了。

ok,上面的办法肯定可以解决也是最应该用的办法,但是我相信很对于很多人尤其是入行不太久的看到这里,应该还是乱乱的,尝试还是解决不掉。没有关系,下面再介绍一种强制关闭tomcat的方法:

方法二:基本原理为启动tomcat时记录启动tomcat的进程id(pid),关闭时强制杀死该进程

1.找到tomcat下bin/catalina.sh文件,vi进去添加点东西,主要是记录tomcat的pid,如下:

大概在第125行左右,添加如下代码

#设置CATALINA_PID(后加)
if [ -z "$CATALINA_PID" ]; then
      CATALINA_PID=$PRGDIR/CATALINA_PID
      cat $CATALINA_PID
fi

保存即可。

2.vi进shutdown.sh文件,在最后一行如下红圈-force:

保存即可.

ok,好了上面即为强制关闭tomcat。希望能帮到你大笑

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值