tomcat为什么无法关闭
执行了tomcat的shutdown脚本后,java进程仍然存在,认为tomcat的关闭脚本不可靠。好吧,其实shutdown.sh无法停止,不是tomcat问题,是应用有问题,否则可以跑一个空tomcat,保证shutdown百分之百生效。
先说一下tomcat的大概关闭过程:
1 停止连接处理线程Accepter,停止接受新的请求
2 关闭tomcat自身的资源,例如各种service,连接器,protocol,container
3 然后tomcat主线程结束了,就是执行BootStrap这个类的线程
这是一个平滑关闭的过程,但是什么时候会导致所谓”tomcat无法关闭”?要更正一点,不是tomcat无法关闭,是执行tomcat的这个jvm无法关闭,这是本质的不同。
最根本的原因是:当前运行tomcat的jvm里还有非deamon的线程没有结束执行,例如被阻塞,或者还在执行任务。这个现象就是tomcat 端口都已经关闭了,但是java进程还在。tomcat的停止只是结束了自己的线程,关闭了自己的资源。但是应用开启的非deamon线程,这个 tomcat是无能为力的。
netstat -ano|grep 8083 /*可以通过此确认tomcat是否已关闭*/
那么JVM什么时候停止?没有非deamon的线程在运行就停止了,或者说应用自身的非deamon线程处理完所有事情结束了自己,jvm就停止了。
那么当发现tomcat停止了,但是ps -ef|grep tomcat进程依然在,如何查看应用那个地方线程是非deamon的呢?
查看办法很简单,执行如下命令:
$JAVA_HOME/bin/jstack <pid>
例:
[root@localhost bin]# ps -ef|grep tomcat
root 1513 1 2 23:41 pts/1 00:00:01 /usr/local/share/java/jdk1.6.0_25/bin/java -Djava.util.logging.config.file=/opt/apache-tomcat-6.0.32/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs=/opt/apache-tomcat-6.0.32/endorsed -classpath /opt/apache-tomcat-6.0.32/bin/bootstrap.jar -Dcatalina.base=/opt/apache-tomcat-6.0.32 -Dcatalina.home=/opt/apache-tomcat-6.0.32 -Djava.io.tmpdir=/opt/apache-tomcat-6.0.32/temp org.apache.catalina.startup.Bootstrap start
root 1544 1462 0 23:42 pts/1 00:00:00 grep --color=auto tomcat
可以看到tomcat进展pid为1513,则下面定位到jdk/bin目录,执行jstack1513 查看 工程里到底哪里开启的新的非守护线程?
$ cd /home/software/jdk1.7.0_79/bin
$ jstack 1513
调用jstack查看:
[root@localhost bin]# jstack 1513
2011-07-12 23:44:00
Full thread dump Java HotSpot(TM) Client VM (20.0-b11 mixed mode, sharing):"Attach Listener" daemon prio=10 tid=0xb41d7c00 nid=0x606 waiting on condition [0x00000000]java.lang.Thread.State: RUNNABLE"TP-Monitor" daemon prio=10 tid=0xb41d6400 nid=0x5fa in Object.wait() [0xb3e0b000]java.lang.Thread.State: TIMED_WAITING (on object monitor)at java.lang.Object.wait(Native Method)- waiting on <0x87143720> (a org.apache.tomcat.util.threads.ThreadPool$MonitorRunnable)at org.apache.tomcat.util.threads.ThreadPool$MonitorRunnable.run(ThreadPool.java:565)- locked <0x87143720> (a org.apache.tomcat.util.threads.ThreadPool$MonitorRunnable)at java.lang.Thread.run(Thread.java:662)"TP-Processor4" daemon prio=10 tid=0xb41d4c00 nid=0x5f9 runnable [0xb3e5c000]java.lang.Thread.State: RUNNABLEat java.net.PlainSocketImpl.socketAccept(Native Method)at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:408)- locked <0x87124770> (a java.net.SocksSocketImpl)at java.net.ServerSocket.implAccept(ServerSocket.java:462)at java.net.ServerSocket.accept(ServerSocket.java:430)at org.apache.jk.common.ChannelSocket.accept(ChannelSocket.java:311)at org.apache.jk.common.ChannelSocket.acceptConnections(ChannelSocket.java:668)at org.apache.jk.common.ChannelSocket$SocketAcceptor.runIt(ChannelSocket.java:879)at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:690)at java.lang.Thread.run(Thread.java:662)
其中看到"Attach Listener" daemon prio=10 tid=0xb41d7c00 nid=0x606 waiting on condition [0x00000000]
java.lang.Thread.State: RUNNABLE
其中主线程不是daemon的,所以是这样:
"main" prio=10 tid=0xb6d05000 nid=0x5ea runnable [0xb6ee9000]java.lang.Thread.State: RUNNABLEat 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)就可以痛痛快快的关闭tomcat,停止应用了。
tomcat为什么无法关闭相关推荐
- tomcat无法正常关闭问题分析及解决
tomcat无法正常关闭问题分析及解决 参考文章: (1)tomcat无法正常关闭问题分析及解决 (2)https://www.cnblogs.com/nuccch/p/9052692.html 备忘 ...
- 阿里云服务器 window server tomcat启动 并且关闭window防火墙 配置8080端口开放还是没用
阿里云windows server 服务器开放端口 1.远程服务器关闭windows防火墙 不需要开放端口 2.阿里云管理平台开放指定的端口 如8081 阿里云服务器 window ser ...
- Linux启动tomcat命令行关闭后服务会停止
最近因为项目需要迁移到云服务器上.自己一个开发还要兼顾运维的事情真是太难了.由于不熟悉.遇到一些各种各样的小坑.在此记录一下. 问题:Linux启动tomcat命令行关闭后服务会停止? 一般Linux ...
- 别人要访问我的电脑上部署的tomcat,必须关闭防火墙吗?
局域网内要访问服务器上部署的tomcat,必须关闭防火墙吗? 不一定. 如果是需要使用 IP:端口号(ip:port)来访问,可以做以下设置(这里仅是说的tomcat访问). 首先在服务器的控制面板中 ...
- 关于运行健康项目的tomcat无法常规关闭现象
20170510 11:29 操作备注:关于健康项目运行后,tomcat无法正常关闭问题的分析.现象:(1)执行tomcat的终止命令之后,使用进程查看命令仍能查看到该tomcat的进程信息存在. ...
- Tomcat启动与关闭事件监听
今天在做项目的时候,需要在tomcat启动的时候便进入某个java类中初始化一些信息.主要是加载数据字典表中的数据.通过学习了tomcat的事件处理机制以及tomcat的生命周期.将该问题成功解决,现 ...
- tomcat ---- 启动,关闭和配置等等
1.启动 在tomcat安装目录的bin文件中双击startup.bat. 2.关闭 在tomcat安装目录的bin文件中双击shutdown.bat. 3.配置tomcat-user.xml文件 ( ...
- tomcat启动与关闭
tomcat经过对应版本的下载解压后应该怎样启动呢? 方式1.找到tomcat下的bin目录下的startup.bat文件,双击就可以启动tomcat服务器了 可见小黑窗口中出现了乱码情况,虽然不会对 ...
- 在eclipse中设置Tomcat启动和关闭时间
然后: 接下来: 按照这样可设置Tomcat的启动和关闭时间,放=方便项目运行.
最新文章
- [转]Getting Start With Node.JS Tools For Visual Studio
- MPLS BGP标签分发过程——Vecloud
- 天通苑海鲜餐馆数据调查,很难想象消费越贵越受欢迎
- XCTF-Reverse:simple-unpack
- 浅谈PostgreSQL的索引
- 安卓ps2模拟器_安卓PSP模拟器评测:合金装备 和平步行者
- windows安装python2
- 在线代码片段管理工具gistbox + github
- SQL service
- [Java] 蓝桥杯ADV-185 算法提高 五次方数
- 航天生物计算机新能源你对哪个领域的课,写作《语言简明》课件.ppt
- mac的一些使用事项
- 排序算法--直接插入排序
- 自媒体文案伪原创文章生成器软件
- 怎样高效地自学软件测试
- PHP实现输入地址,获取当前位置的经纬度,$lng和$lat即为经纬度的返回值
- 没有NumLock键的小键盘误触变成方向键
- 胃酸过多症的食疗方 [转]
- 硬笔书法“案”字怎样书写正确?“最美中国字”来教你!
- RabbitMQ实战教程