记Tomcat进程stop卡住问题定位处理
部分内容参考自CSDN
测试环境通过agent注入了部分代码,其中包括几个Timer.
在通过启动脚本重启tomcat时,会一直有一个stop进程卡住,导致tomcat无法正常重启,进程卡住不动。
通过jstack tomcat进程,发现没有死锁进程,只有两个进程是TIMED_WAITING,这两个进程是通过agent注入的两个原生timer,原生timer很不建议使用.
/**
* 1.获取路由节点队列数据,超过Config.Message.NODES大小发送至GRCC
*/
new Timer("route-nodes-to-grcc-timer-1").scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
try {
while (true) {
try {
if(isCanPoll){
Node node = nodesLinkedQueue.poll();
if(null != node){
nodes.add(node);
if(nodes.size() >= Config.Message.NODES){
try{
semaphore.acquire();
if(!nodes.isEmpty()){
sendToGRCC(nodes);
}
}catch (Exception e){
logger.error("Consumer Task发送链路信息至GRCC异常,异常信息如下:"+e.getMessage());
}finally {
semaphore.release();
}
}
}
}
Thread.sleep(10L);
} catch (Exception e) {
logger.error("nodesLinkedQueue poll异常,错误信息如下:"+e.getMessage());
}
}
} catch (Exception e) {
logger.error("schedule执行异常,错误信息如下:"+e.getMessage());
}
}
}, 1000L, 1000L); /**
* 2.间隔Config.Message.INTERVAL时间发送一次路由节点信息至GRCC
*/
new Timer("route-nodes-to-grcc-timer-2").scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
/**
* nodes不为null再获取锁进行发送
*/
if (!nodes.isEmpty()) {
try {
semaphore.acquire();
isCanPoll = false;
if (!nodes.isEmpty()) {
sendToGRCC(nodes);
}
} catch (Exception e) {
logger.error("Schedule Task发送链路信息至GRCC异常,异常信息如下:" + e.getMessage());
} finally {
semaphore.release();
isCanPoll = true;
}
}
}
},1000L,Config.Message.INTERVAL);
每次tomcat重启时,进程卡住的同时,后端tomcat日志会打印如下类似的提示内存泄漏的warning:
02-Jan-2019 19:37:46.918 警告 [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [fx-route] appears to have started a thread named [dubbo-remoting-client-heartbeat-thread-2] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093)
java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
java.lang.Thread.run(Thread.java:745)
02-Jan-2019 19:37:46.920 警告 [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [fx-route] appears to have started a thread named [pool-13-thread-1] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093)
java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
java.lang.Thread.run(Thread.java:745)
02-Jan-2019 19:37:46.922 警告 [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [fx-route] appears to have started a thread named [pool-14-thread-1] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093)
java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
java.lang.Thread.run(Thread.java:745)
02-Jan-2019 19:37:46.923 警告 [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [fx-route] appears to have started a thread named [Abandoned connection cleanup thread] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.lang.Object.wait(Native Method)
java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
com.mysql.jdbc.NonRegisteringDriver$1.run(NonRegisteringDriver.java:93)
通过查询,发现上述CSDN中描述的:存在线程未关闭,比如Timer。
后来将Timer修改为ScheduledExecutorService后,发现tomcat启动正常。
ScheduledExecutorService executor = Executors.newScheduledThreadPool(2,new DefaultNamedThreadFactory("route-nodes-to-grcc"));
/**
* 1.获取路由节点队列数据,超过Config.Message.NODES大小发送至GRCC
*/
executor.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
try {
while (true) {
try {
if(isCanPoll){
Node node = nodesLinkedQueue.poll();
if(null != node){
nodes.add(node);
if(nodes.size() >= Config.Message.NODES){
try{
semaphore.acquire();
if(!nodes.isEmpty()){
sendToGRCC(nodes);
}
}catch (Exception e){
logger.error("Consumer Task发送链路信息至GRCC异常,异常信息如下:"+e.getMessage());
}finally {
semaphore.release();
}
}
}
}
Thread.sleep(10L);
} catch (Exception e) {
logger.error("nodesLinkedQueue poll异常,错误信息如下:"+e.getMessage());
}
}
} catch (Exception e) {
logger.error("schedule执行异常,错误信息如下:"+e.getMessage());
}
}
},1000L, 1000L, TimeUnit.MILLISECONDS);
/**
* 2.间隔Config.Message.INTERVAL时间发送一次路由节点信息至GRCC
*/
executor.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
/**
* nodes不为null再获取锁进行发送
*/
if (!nodes.isEmpty()) {
try {
semaphore.acquire();
isCanPoll = false;
if (!nodes.isEmpty()) {
sendToGRCC(nodes);
}
} catch (Exception e) {
logger.error("Schedule Task发送链路信息至GRCC异常,异常信息如下:" + e.getMessage());
} finally {
semaphore.release();
isCanPoll = true;
}
}
}
},1000L,Config.Message.INTERVAL,TimeUnit.MILLISECONDS);
阿里编程规范有如下两条:
- 【规范】线程资源必须通过线程池提供,不允许在应用中自行显式创建线程。
说明:使用线程池的好处是减少在创建和销毁线程上所花的时间以及系统资源的开销,解决资源不足的问题。如果不使用线程池,有可能造成系统创建大量同类线程而导致消耗完内存或者 “过度切换”的问题。 - 【规范】线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
说明:Executors 返回的线程池对象的弊端如下:
1)FixedThreadPool 和 SingleThreadPool:
允许的请求队列长度为 Integer.MAX_VALUE,可能会堆积大量的请求,从而导致 OOM。
2)CachedThreadPool 和 ScheduledThreadPool:
允许的创建线程数量为 Integer.MAX_VALUE,可能会创建大量的线程,从而导致 OOM。
记Tomcat进程stop卡住问题定位处理的更多相关文章
- (转)tomcat进程意外退出的问题分析
节前某个部门的测试环境反馈tomcat会意外退出,我们到实际环境排查后发现不是jvm crash,日志里有进程销毁的记录,从pause到destory的整个过程: org.apache.coyote. ...
- window 和 linux 环境下杀死tomcat进程——也可以解决其他端口被占用的问题
1.应用场景 在Windows或者linux操作系统中,我们在启动一个tomcat服务器时,经常会发现8080端口已经被占用的错误,而我们又不知道如何停止这个tomcat服务器. 2.window环境 ...
- 在Windows操作系统中,如何终止占有的8080端口的tomcat进程
在Windows操作系统中,我们在启动一个tomcat服务器时,经常会发现8080端口已经被占用的错误,而我们又不知道如何停止这个tomcat服务器. 本文将通过命令来强行终止这个已经运行的tomca ...
- linux下shutdown无法关闭tomcat进程的解决方式
1.问题 笔者在linux下发现使用tomcat6.0.41自带的./shutdown.sh常常无法停止进程,导致各种问题的发生,令笔者相当反感! 2.解决方式一: 查找到全部的tomcat进程 $ ...
- Linux下tomcat管理查看控制台|杀死tomcat进程
查看控制台 # tail -f catalina.out 脚本执行权限chmod u+x *.sh #看是否已经有tomcat在运行了 ps -ef |grep tomcat #如果有,用kill; ...
- windows和linux下关闭Tomcat进程
windows和linux下解决Tomcat进程 windows下启动Tomcat报错,8080端口号被占用,报错信息如下 两种解决方法,一种是关闭了这个端口号,另外一种是修改Tomcat下的serv ...
- tomcat 进程莫名停止
背景: 有一次晚上下班,发完版,刚把电脑合上走到楼下,就接到报警,说是线上有一个tomcat进程不存在了,想着以为是误报,但是还是回去看看了,发现线上确实是刚才发版的项目,进程不存在了,想了想,刚才测 ...
- tomcat启动时卡住
tomcat启动时卡住 进入jdk/jre/lib/security/java.security文件 找到securerandom.source将这一行隐藏 并在下面一行加入securerandom. ...
- jstat命令查看tomcat进程提示进程没找到(PID not found
今天遇到了一个小问题,我想用jstat命令查看tomcat进程(PID=24493)的内存使用情况,命令如下:jstat -gc 24493. 然后就报错了,错误提示信息为 24493 not fou ...
随机推荐
- HR问“你目前有几个offer”,聪明人会怎么说?
点击上方“程序员江湖”,选择“置顶或者星标” 你关注的就是我关心的! 一个朋友和我聊天,说起自己最近被虐的面试经历.他985毕业,工作3年,看中了一家月薪1.5万的工作,准备跳槽.虽然在北京不算高 ...
- python3笔记二十二:正则表达式之函数
一:学习内容 re.match函数 re.search函数 re.findall函数 二:re.match函数 需要导入包:import re 1.格式:match(pattern,string,fl ...
- js对象之间的"继承"的五种方法
今天要介绍的是,对象之间的"继承"的五种方法. 比如,现在有一个"动物"对象的构造函数. function Animal(){ this.species = & ...
- Python基于Pymssql模块实现连接SQL Server数据库的方法
首先,安装pymssql第三方库pip install pymssql 其次,导入pymssql库 最后们就可以连接数据库了 import pymssql server = "10.10.9 ...
- shell脚本--监控java进程存活脚本
#!/bin/bash base_dir=/opt war_processor="tomcat" jar_processor="manager-server.jar pl ...
- EXCEL中自定义格式输入的数据怎么完整复制
在用设置单元格式里 自定义 输入数值 如图,B列的数据,我复制后,用选择性粘贴到别的地方,还是无法将75FG4Y2一起复制过去,只能复制过去FG 怎么办? ===>先把这些复制到一个记事本里,再 ...
- tab切换效果 网站中的图片自动切换
网站中的图片自动切换 今天上一套tab切换效果的代码 动图就自己实现吧! 下面贴HTML代码,大体分两部分,图片div和按钮div,代码很容易看懂~ <!DOCTYPE html> < ...
- python 类中__getattr__的使用
class F: def __init__(self, name): self.name = name def __getattr__(self, item): return '__getattr__ ...
- .NetCore 使用VSCode多项目调试
使用VSCode可以调试.Net Core,但是调多个项目就需要进行一番设置. 首先创建一个总文件夹,以NetProjects文件夹为例,并创建一个解决方案.然后创建俩个.NetCore项目,并添加到 ...
- [译]AngularJS 1.3.0 开发者指南(一) -- 介绍 (转)
http://www.cnblogs.com/lzj0616/p/6440563.html [译]AngularJS 1.3.0 开发者指南(一) -- 介绍 Angular是什么 ? Angular ...